博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
05,总结——关于用户登录以及注册
阅读量:4948 次
发布时间:2019-06-11

本文共 7528 字,大约阅读时间需要 25 分钟。

 

用户登录与注册是每个网站、app中最重要的知识点!它直接涉及到了用户的基本信息,帐号的安全。因此设计好用户的登录与注册在开发中显得尤其重要,这几天正好学习玩了drf,是时候来一波总结了——关于用户登录与注册方面的。当然,本次的总结会结合更早期原生DjangoForm方式的登录来做一次对比。希望能够搞清楚一些问题!

用户登录

不管是有没有用到前后端分离,其实用户登录最核心的思想是没有变化的——拿到前端传递过来的用户名以及密码,在数据库中对用户名或密码进行检验,存在此用户则通过,不存在则抛出异常。
基于DjangoForm的用户登录
model的设计
from django.db import models from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): """继承AbstractUser表并向里加几条数据""" phone = models.CharField(max_length=11, null=True, unique=True, verbose_name="手机号码") avatar = models.FileField(upload_to="media/avatars", default="static/img/touxiang.jpg", verbose_name="头像") create_time = models.DateTimeField(auto_now_add=True, verbose_name="用户角色创建时间") class Meta: verbose_name = "用户" verbose_name_plural = verbose_name<wiz_code_mirror>
 
 
 
13
 
 
 
 
 
1
from django.db import models
2
from django.contrib.auth.models import AbstractUser
3
 
4
 
5
class UserInfo(AbstractUser):
6
   """继承AbstractUser表并向里加几条数据"""
7
   phone = models.CharField(max_length=11, null=True, unique=True, verbose_name="手机号码")
8
   avatar = models.FileField(upload_to="media/avatars", default="static/img/touxiang.jpg", verbose_name="头像")
9
   create_time = models.DateTimeField(auto_now_add=True, verbose_name="用户角色创建时间")
10
 
11
   class Meta:
12
       verbose_name = "用户"
13
       verbose_name_plural = verbose_name
 
 
继承的是AbstractUser,继承AbstractUser的好处:
1)内置了很多字段不用自己重写
2)内置了密码加密,可以直接用
def set_password(self, raw_password): self.password = make_password(raw_password) # 点击进入make_password self._password = raw_password<wiz_code_mirror>
 
 
 
3
 
 
 
 
 
1
   def set_password(self, raw_password):
2
       self.password = make_password(raw_password)    # 点击进入make_password
3
       self._password = raw_password
 
 
def make_password(password, salt=None, hasher='default'): """ Turn a plain-text password into a hash for database storage Same as encode() but generate a new random salt. If password is None then return a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string, which disallows logins. Additional random string reduces chances of gaining access to staff or superuser accounts. See ticket #20079 for more info. """ if password is None: return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH) hasher = get_hasher(hasher) if not salt: salt = hasher.salt() return hasher.encode(password, salt)<wiz_code_mirror>
 
 
 
17
 
 
 
 
 
1
def make_password(password, salt=None, hasher='default'):
2
   """
3
   Turn a plain-text password into a hash for database storage
4
 
5
   Same as encode() but generate a new random salt. If password is None then
6
   return a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string,
7
   which disallows logins. Additional random string reduces chances of gaining
8
   access to staff or superuser accounts. See ticket #20079 for more info.
9
   """
10
   if password is None:
11
       return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH)
12
   hasher = get_hasher(hasher)
13
 
14
   if not salt:
15
       salt = hasher.salt()
16
 
17
   return hasher.encode(password, salt)
 
 
Django内置的帮助我们把保存至数据库的密码进行了加密操作,而且是不可逆的!
在前后端分离的项目中对用户的密码进行加密也有用到了这一点
def create(self, validated_data): """对密码进行加密""" user = super(UserRegSerializer, self).create(validated_data=validated_data) # 获取user user.set_password(validated_data['password']) # 用起来非常的方便只需要传入密码即可 user.save() return user<wiz_code_mirror>
 
 
 
6
 
 
 
 
 
1
def create(self, validated_data):
2
       """对密码进行加密"""
3
       user = super(UserRegSerializer, self).create(validated_data=validated_data)  # 获取user
4
       user.set_password(validated_data['password'])    # 用起来非常的方便只需要传入密码即可
5
       user.save()
6
       return user
 
 
这里下面会进行详解!
一套完整的流程是这样的。
1、urls.py
path('login/', views.login, name="login"),<wiz_code_mirror>
 
 
 
1
 
 
 
 
 
1
path('login/', views.login, name="login"),
 
 
2、views.py
def login(request): if request.method == "POST": ret = {"status": True, "msg": ""} login_form = LoginForm(request.POST) if login_form.is_valid(): user = login_form.cleaned_data["user"] auth.login(request, user) # 登录之后返回某个页面 ret["msg"] = "/index/" return JsonResponse(ret) else: ret["status"] = False ret['msg'] = login_form.errors return JsonResponse(ret) login_form = LoginForm() context = {} context['login_form'] = login_form return render(request, 'login.html', context)<wiz_code_mirror>
 
 
 
20
 
 
 
 
 
1
def login(request):
2
   if request.method == "POST":
3
       ret = {
"status": True, "msg": ""}
4
       login_form = LoginForm(request.POST)
5
       if login_form.is_valid():
6
           user = login_form.cleaned_data["user"]
7
           auth.login(request, user)
8
           # 登录之后返回某个页面
9
           ret["msg"] = "/index/"
10
           return JsonResponse(ret)
11
 
12
       else:
13
           ret["status"] = False
14
           ret['msg'] = login_form.errors
15
           return JsonResponse(ret)
16
 
17
   login_form = LoginForm()
18
   context = {}
19
   context['login_form'] = login_form
20
   return render(request, 'login.html', context)
 
 
3、forms.py
class LoginForm(forms.Form): username = forms.CharField( min_length=8, max_length=16, label='用户名', error_messages={ "required": "用户名不能为空", "max_length": "用户名不能超过16位", "min_length": "用户名不能小于8位", }, widget=forms.widgets.TextInput( attrs={"class": "form-control", "placeholder": "请输入用户名"}), ) password = forms.CharField( min_length=8, max_length=16, label='密码', error_messages={ "required": "用户名不能为空", "max_length": "用户名不能超过16位", "min_length": "用户名不能小于8位", }, widget=forms.widgets.PasswordInput( attrs={"class": "form-control", "placeholder": "请输入密码"}, ) ) def clean(self): """ 用户登录的校验该怎么做? 用户输入帐号、密码去数据库中查找是否输入正确 auth模块下的authenticate :return: """ username = self.cleaned_data.get("username") password = self.cleaned_data.get("password") user = auth.authenticate(username=username, password=password) # 去数据库中查找用户填写的帐号、密码 if user is None: raise ValidationError("用户名或密码不正确!") else: self.cleaned_data['user'] = user return self.cleaned_data<wiz_code_mirror>
 
 
 
x
 
 
 
 
 
1
class LoginForm(forms.Form):
2
   username = forms.CharField(
3
       min_length=8,
4
       max_length=16,
5
       label='用户名',
6
       error_messages={
7
           "required": "用户名不能为空",
8
           "max_length": "用户名不能超过16位",
9
           "min_length": "用户名不能小于8位",
10
       },
11
       widget=forms.widgets.TextInput(
12
           attrs={
"class": "form-control", "placeholder": "请输入用户名"}),
13
   )
14
 
15
   password = forms.CharField(
16
       min_length=8,
17
       max_length=16,
18
       label='密码',
19
       error_messages={
20
           "required": "用户名不能为空",
21
           "max_length": "用户名不能超过16位",
22
           "min_length": "用户名不能小于8位",
23
       },
24
       widget=forms.widgets.PasswordInput(
25
           attrs={
"class": "form-control", "placeholder": "请输入密码"},
26
       )
27
   )
28
 
29
   def clean(self):
30
       """
31
       用户登录的校验该怎么做?
32
       用户输入帐号、密码去数据库中查找是否输入正确 auth模块下的authenticate
33
       :return:
34
       """
35
       username = self.cleaned_data.get("username")
36
       password = self.cleaned_data.get("password")
37
       user = auth.authenticate(username=username, password=password)   # 去数据库中查找用户填写的帐号、密码
38
       if user is None:
39
           raise ValidationError("用户名或密码不正确!")
40
       else:
41
           self.cleaned_data['user'] = user
42
       return self.cleaned_data
 
 
 
这里面有一个重中之重的知识点,就是DjangoForm的验证过程。查看源码即可知道
04,Django Form源码阅读
基于前后端分离的用户登录
models.py
同样是继承了AbstractUser!<wiz_code_mirror>
 
 
 
 
 
 
 
 
 
1
同样是继承了AbstractUser!
 
 
前后端分离的方式实现用户登录其实有很多种方法来进行,跟着bobby老师所讲述的就有三种方式。
 
 
 
 
 

转载于:https://www.cnblogs.com/pontoon/p/10217383.html

你可能感兴趣的文章
JavaScript对象及初识面向对象
查看>>
mac安装nose,command not found:nosetests
查看>>
抓取cntv电视节目表
查看>>
【刷题】洛谷 P3613 睡觉困难综合征
查看>>
操作系统简介
查看>>
过滤器和拦截器的区别
查看>>
jdk 设计模式
查看>>
js对话框弹窗
查看>>
.NET中怎么有效的使用Cache
查看>>
结对学习感想
查看>>
Tomcat源码分析(从启动流程到请求处理)
查看>>
onPullDownRefresh函数没有被正确执行
查看>>
【原创】Activity 概念介绍(大全)
查看>>
从零讲解搭建一个NIO消息服务端
查看>>
VS 插件
查看>>
Chrome 消息传递机制
查看>>
性能测试插件
查看>>
全站缓存时代
查看>>
http://javafound.iteye.com/blog/704141 微博是这样练成的
查看>>
[MPI学习笔记]mpi并行实现方法
查看>>