05,总结——关于用户登录以及注册

 

用户登录与注册是每个网站、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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值