Django笔记-Django自定义用户验证实现用户登录

Django笔记-Django自定义用户验证实现用户登录

Django自带的用户认证后端默认是使用用户名实现用户认证的。用户认证后端位置为django.contrib.auth.backends.ModelBackend

  • 需求

    实现用户名和手机号都可以认证一个用户

  • 编写一个认证后端

    认证后端是一个类,它实现了两个必要的方法get_user(user_id) 和 authenticate(request, **credentials)。
    1. get_user 方法接收一个 user_id ——可以是用户名、电话号码,或者其他唯一标识用户的信息——然后返回一个用户对象或 None。
    2.authenticate 方法采用 request 参数和证书作为关键字参数

  • 自定义编写一个认证后端步骤

    1.在users子应用下新建py文件utils.py,定义一个类为AuthPasswordUsernameModelBackend继承django.contrib.auth.backends.ModelBackend

    2.重写authenticate,get_user方法

    import re
    
    from django.contrib.auth.backends import ModelBackend
    from users.models import User
    
    
    
    def get_account(user_id):
        try:
            if re.match(r'^1[3-9]\d{9}$', user_id):
                user = User.objects.get(mobile__exact=user_id)
            else:
                user = User.objects.get(username__exact=user_id)
        except User.DoesNotExist as e:
            return None
        return user
    
    
    class AuthPasswordUsernameModelBackend(ModelBackend):
        def authenticate(self, request, username=None, password=None, **kwargs):
            user = get_account(user_id=username)
            if user and user.check_password(password):
                return user
            return None
    
  • 在配置文件中指定自定义验证后端

    AUTHENTICATION_BACKENDS = ['users.utils.AuthPasswordUsernameModelBackend']
    
  • 定义登录接口

    请求方法:post
    请求地址:http://127.0.0.1:8000/login
    请求参数:username(可以为用户名或者手机号),password
    返回参数:json

  • 编写登录视图和配置子路由

    1.配置子路由:

    from django.urls import re_path, path
    from users.views import *
    
    urlpatterns = [
        path('login/', LoginView.as_view())#登录
        path('register/', RegisterView.as_view())#注册
    ]
    

    2.编写登录视图

    from django.contrib.auth import login, authenticate
    from django.views import View
    from django import http
    from django.db import DataError
    from django.db.models import Q
    
    from users.models import User
    
    import json
    import re
    
    
    # Create your views here.
    class LoginView(View):
        # @csrf_protect
        def post(self, request):
            json_str = request.body.decode()
            if json_str.strip('') == '':
                return http.JsonResponse({'errmsg': '缺少参数'})
            json_dict = json.loads(json_str)
            username = json_dict.get('username')
            password = json_dict.get('password')
            if not all([username, password]):
                return http.JsonResponse({
                    'errmsg': '缺少必传参数'
                })
            """
            from django.contrib.auth import authenticate
            调用auth模块中的authenticate方法,传入用户名或手机号和密码,该方法会自动
            调用自定义配置的认证后端进行用户身份认证
            """
            
            user = authenticate(username=username, password=password)
            if user is None:
                return http.JsonResponse({
                    'errmsg': '密码错误'
                })
            """
          	login()方法实现用户登录,将用户的id,以及user_backend写入session存入缓存
    		实现会话持久化。
            """
            login(request, user)
           	request.session.set_expiry(300)
            return http.JsonResponse({
                'errmsg': 'ok'
            })
    

    关于request.session.set_expiry(value):设置当前request请求中user对象的会话过期时间。
    value参数:
    1).整型:

    value=0:表示用户在关闭浏览器后会话就过期,则数据库或者缓存中的session被删除 。
    value>0:设置过期秒数(300s, 5分钟)

    2)日期:

    如果 value 是一个 datetime 或 timedelta 对象,会话将在指定的 date/time 过期。
    如果在登录时没有设置session的过期时间,默认为session全局过期策略,也就是全局配置文件下的配置项SESSION_COOKIE_AGE= 86400(这里我设置为1天的过期时间),Django默认的session会话过期时间为1209600(也就是两周)

  • 测试

    用户记录

    在这里插入图片描述
    在这里插入图片描述

    1.postman用户名登录测试
    Django笔记-Django自定义用户验证实现用户登录_第1张图片

    2.查看cookies

    在这里插入图片描述

    3.postman 手机号登录
    Django笔记-Django自定义用户验证实现用户登录_第2张图片
    4.查看cookies
    Django笔记-Django自定义用户验证实现用户登录_第3张图片

    上一篇-django注册用户 https://blog.csdn.net/adminwg/article/details/126179786

你可能感兴趣的:(django,django,python,后端)