zoukankan      html  css  js  c++  java
  • 使用用户名/邮箱/手机号 + 密码登陆 多形式登陆

    使用用户名/邮箱/手机号 + 密码登陆

    • 多形式登陆其实很简单就是继承Django中ModelBackend并且重写authenticate()方法

    源码分析:

    class ModelBackend:
        """
        Authenticates against settings.AUTH_USER_MODEL.
        """
    
        def authenticate(self, request, username=None, password=None, **kwargs):
            if username is None:
                username = kwargs.get(UserModel.USERNAME_FIELD)
            try:
                user = UserModel._default_manager.get_by_natural_key(username)
            except UserModel.DoesNotExist:
                # Run the default password hasher once to reduce the timing
                # difference between an existing and a nonexistent user (#20760).
                UserModel().set_password(password)
            else:
                if user.check_password(password) and self.user_can_authenticate(user):
                    return user
    
    

    通过查看源码我们可以看到Django默认的认证后端是判断用户的username和password这两个字段是否通过校验,但实际上,我们可能会有更多的登录需求,比如说,既可以通过用户名,也可以通过手机号或邮箱等登录,这时候我们可以重写authenticate()方法实现

    1.我们新建一个py文件里面写一个类继承ModelBackend,并且重写authenticate()方法

    第一种方法:这种方法通俗简单易懂

    # 以前使用username进行用户验证,现在修改成email|phone进行验证 多形式登录
    from user.models import User
    
    class EmailAuthBackend:
        def authenticate(self, request, username=None, password=None):
            try:
                user = User.objects.get(username=username)
            except Exception as e:
                user = None
            if not user:
                try:
                    user = User.objects.get(email=username)
    
                except Exception as e:
                    user = None
            if not user:
                try:
                    user = User.objects.get(phone=username)
    
                except Exception as e:
                    user = None
    
            if user and user.check_password(password):
                return user
            else:
                return None
    
        def get_user(self, user_id):
            try:
                return User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return None
    

    第二种方法:使用Q对象。( | )来获取username phone email

    from django.contrib.auth.backends import ModelBackend
    from user import models
    from django.db.models import Q
    
    
    class MultiformAuthBackend(ModelBackend):
        def authenticate(self, request, username=None, password=None, **kwargs):
            try:
                user = User.objects.get(Q(username=username) | Q(phone=username) | Q(email=username))
                if user is not None and user.check_password(password):
                    return user
            except Exception as e:
                print(e)
    

    2.在setting.py配置文件

    • 完成自定义的认证后端之后,我们还需要在配置文件里告诉Django要使用我们自定义的而不是默认的认证后端
    # 自定义验证后端 多形式登录
    # AUTHENTICATION_BACKENDS = ['user.utils.EmailAuthBackend']
    AUTHENTICATION_BACKENDS = ['user.utils.MultiformAuthBackend']
    

    其他类似链接参考:
    【Django】创建用户,继承AbstractUser自定义用户模型类
    【Django】自定义存储后端返回完整图片的URL链接

    从小白到大神的蜕变~~
  • 相关阅读:
    软件定义网络实验4:Open vSwitch 实验——Mininet 中使用 OVS 命令(实验过程及结果记录)
    软件定义网络实验3:测量路径的损耗率 (实验过程及结果记录)
    第一次个人编程作业
    软件定义网络实验2:Mininet拓扑的命令脚本生成(实验过程及结果记录)
    软件定义网络实验1:Mininet源码安装和可视化拓扑工具(实验过程及结果记录)
    第一次博客作业
    第07组(69) 需求分析报告
    第七组(69)团队展示
    第三次作业
    结对编程作业
  • 原文地址:https://www.cnblogs.com/tjw-bk/p/13935859.html
Copyright © 2011-2022 走看看