首页 > 编程语言 >drf重写authenticate方法实现多条件登录(源码分析)

drf重写authenticate方法实现多条件登录(源码分析)

时间:2023-05-10 23:23:31浏览次数:44  
标签:username account authenticate django 源码 user 重写 drf

drf重写authenticate方法实现多条件登录(源码分析)

1. 思路

JWT拓展的登录视图中, 在接受到用户名和密码时, 调用的也是Django的认证系统中提供的authenticate()来检查用户名与密码是否正确.

我们可以通过修改Django系统的认证后端来支持登录账号既可以是用户名也可以是手机号

修改重写思路是:

修改Django认证系统的认证后端需要继承django.contrib.auth.backends.ModelBackends, 并重写authenticate方法

我们需要重写什么位置?

因为我们的需求是多条件登录, 所以我们就应该着手于数据库校验操作, 寻找定位源码中数据库校验username是否存在的操作, 并使用Q查询添加多个条件验证

2. 源码分析

下面是以from rest_framework_jwt.views import obtain_jwt_token为入口进行的源码分析(序号为查找流程):

  • 继承JsonWebTokenAPIView视图, 当接受到用户post请求时, 执行get_serializer()

  • 调用get_serializer()方法找到子类中定义的serializer类

  • 当调用is_valid()方法时, 会调用到validate()

  • 这里调用了authenticate方法并传入了用户数据, 返回的对象user

  • authenticate方法中调用了_get_backneds()方法, 此方法中将配置文件AUTHENTICATION_BACKENDS读取, 这个是django默认的配置, 我们重写方法之后, 需要将我们的类也配置到这里
  • django的默认配置文件路径 django>conf>global_settings.py>AUTHENTICATION_BACKENDS
  • 读取了配置文件之后调用到了ModelBackend中的authenticate方法
  • authenticate方法
    • 获取username
    • 携带username进行查表操作, 返回user对象
    • 如果查到user,就去验证其密码的正确性
  • 所以我们就可以重写的ModelBackend中的authenticate方法(修改数据库操作)

3. 代码实现

在utils/authenticate.py中:

from django.contrib.auth.backends import ModelBackend, UserModel
from django.db.models import Q


def get_user_by_account(account):

    """
    根据帐号信息获取user模型实例对象
    :param account: 账号信息,可以是用户名,也可以是手机号,甚至其他的可用于识别用户身份的字段信息
    :return: User对象 或者 None
    """
    user = UserModel.objects.filter(Q(mobile=account) | Q(username=account) | Q(email=account)).first()
    return user


class CustomAuthBackend(ModelBackend):
    """
    自定义用户认证类[实现多条件登录]
    """
    def authenticate(self, request, username=None, password=None, **kwargs):
        """
        多条件认证方法
        :param request: 本次客户端的http请求对象
        :param username:  本次客户端提交的用户信息,可以是user,也可以mobile或其他唯一字段
        :param password: 本次客户端提交的用户密码
        :param kwargs: 额外参数
        :return:
        """
        if username is None:
            username = kwargs.get(UserModel.USERNAME_FIELD)

        if username is None or password is None:
            return
        # 根据用户名信息useranme获取账户信息
        user = get_user_by_account(username)
        if user and user.check_password(password) and self.user_can_authenticate(user):
            return user

在配置文件settings/dev.py中告知Django使用我们自定义的认证后端,注意不是给drf添加设置。

# django自定义认证

AUTHENTICATION_BACKENDS = ['luffycityapi.utils.authenticate.CustomAuthBackend', ]

标签:username,account,authenticate,django,源码,user,重写,drf
From: https://www.cnblogs.com/huxiaofeng1029/p/17389686.html

相关文章

  • java基于springboot+vue的房屋租赁租房系统、租房管理系统,附源码+数据库,免费包运行,适
    1、项目介绍java基于springboot+vue的房屋租赁租房系统、租房管理系统,分为管理员和用户。用户的功能有:登录、注册、房屋信息、交流论坛、房屋咨询、在线客服、个人中心、我的收藏、我的发布、预约看房管理、在线签约管理、租赁评价管理、管理员的功能有:登录、个人中心、用户管......
  • 开源单用户客服系统源码-上传附件功能-elementui 异步上传文件【唯一客服开发商】
    之前开源的单用户客服系统,上传附件成功后,还不能展示出文件形式,今天把上传展示出文件形式给开发完善一下。我想要实现的效果是,展示出文件的名称和大小信息后端返回一个带有文件信息的json结果,前端把该信息组织一下并解析成可以展示的样子后端golang部分代码funcUploadFile(c......
  • DIY EMGUCV4.7.0 源码生成库方式
    背景项目由NetFrameWork4.5升级到NetCore7。以前版本的EMGUCV无法使用了,下载下来的4.7版本无法使用。采用自己根据开发电脑环境(Win10)生成方式使用。部署方式未fq。使用工具VS2022。步骤1.下载EMGUCV项目gitclonehttps://github.com/emgucv/emgucv.git2.将仓库中......
  • 直播app系统源码,dialogfragment设置底部没有和屏幕有间隔
    直播app系统源码,dialogfragment设置底部没有和屏幕有间隔 @Override  publicvoidonStart(){    super.onStart();    Windowwindow=getDialog().getWindow();    if(window!=null){      //设置window的背景色为透明色. ......
  • 直播网站源码,安卓防止输入框自动弹出
    直播网站源码,安卓防止输入框自动弹出可以在edittext的父布局结构中(例如LinearLayout,RelativeLayout等)添加  android:focusable="true" android:focusableInTouchMode="true"​以上就是直播网站源码,安卓防止输入框自动弹出,更多内容欢迎关注之后的文章 ......
  • 龙芯3a5000处理器下编译Qt源码
    1、下载Qt源码,archive/qt/5.12/5.12.8/single/qt-everywhere-src-5.12.8.tar.xz2、安装依赖库:sudoapt-getinstallflexsudoapt-getinstallbisonsudoapt-getinstallgperfsudoapt-getinstallbuild-essentialsudoapt-getinstalllibgl1-mesa-devsudoapt-getin......
  • 4.Spring之依赖注入源码解析
    Spring中到底有几种依赖注入的方式?首先分两种:手动注入自动注入手动注入在XML中定义Bean时,就是手动注入,因为是程序员手动给某个属性指定了值。<beanname="userService"class="com.luban.service.UserService"> <propertyname="orderService"ref="orderService"/>&l......
  • 如何进行MySQL源码调试(一条select语句的执行流程)
    一、背景MySQL是当今世上最受欢迎的使用最广泛的开源数据库,它的繁荣离不开它的开源特性。放在过去商业数据库的时代,大家都没有机会接触到数据库的源代码,但在如今开源数据库的时代,越来越多的人开始研究数据库的源码,并给社区贡献代码,MySQL官方每次发布新版本都要感谢一些在社区上贡......
  • Kotlin源码分析
    Compiler目录clisrc下面的是命令行下的编译入口,包括了jvm,重点是K2JVMCompiler执行编译过程和命令行接口CLITool|--CLICompiler|--K2JSCompiler|--K2JsIrComiler|--K2JVMCompiler|--K2MetadataCompilerCLITool|--doMain|--exec|--execImpl|--createArgument|--parseA......
  • 在线直播源码,java数据分页几种方式
    在线直播源码,java数据分页几种方式1.使用PageUtils Service: /**   *分页查询   *   *@paramparams查询条件   *@returnPageUtils   */  PageUtilsqueryPage(Map<String,Object>params);   ServiceImpl: Page<数据库对象实体>pa......