Django contrib auth authenticate函数源码解析

 更新时间:2020年11月12日 14:47:10   作者:codeLeaves  
这篇文章主要介绍了Django contrib auth authenticate函数源码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

引言

django提供了一个默认的auth系统用于用户的登录和授权,并提供了一定的扩展性,允许开发者自行定义多个验证后台,每个验证后台必须实现authenticate函数,并返回None或者User对象。

默认的后台是django.contrib.auth.backends.ModelBackend,该后台通过用户名和密码进行用户的验证,以settings.AUTH_USER_MODEL作为模型。但是在实际的开发中,相信大家都不会固定的使用用户名以及同一个model进行验证,比如,不同的角色需要不同的model作为验证的数据源,有的角色是使用手机登录,而有的角色使用邮箱登录。

那么,当存在多个验证后台的时候,django是如何制作一个统一的接口进行不同后台的验证呢?

authenticate函数分析

源码:

def authenticate(**credentials):
  """
  If the given credentials are valid, return a User object.
  """
  for backend, backend_path in _get_backends(return_tuples=True):
    try:
      inspect.getcallargs(backend.authenticate, **credentials)
    except TypeError:
      # This backend doesn't accept these credentials as arguments. Try the next one.
      continue

    try:
      user = backend.authenticate(**credentials)
    except PermissionDenied:
      # This backend says to stop in our tracks - this user should not be allowed in at all.
      break
    if user is None:
      continue
    # Annotate the user object with the path of the backend.
    user.backend = backend_path
    return user

  # The credentials supplied are invalid to all backends, fire signal
  user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials))

**credentials

首先可以看到authenticate函数接受的参数,这是指authenticate函数只接受关键字传参,位置传参是不允许的。因此在使用authenticate函数的时候注意不要为了省事而位置传参。

# This will fail
user = authenticate('username', 'password')

# This will success
user = authenticate(username='username', password='password')

inspect.getcallargs(func, *args, **kwargs)
inspect模块是Python官方的标准模块,这个模块对Python的自省功能进行一定的封装。其中inspect.getcallargs检查args和kwargs这些参数是否能被func要求的参数匹配,若匹配成功返回参数字典,如果不能匹配就会raise TypeError。
举个简单的例子。假设在Python中定义这样一个函数:

import inspect
def test_func(arg1, arg2, *args, **kwargs):
  pass
# this will raise TypeError
inspect.getcallargs(test_func, a=1, b=2, c=3)
# TypeError: test_func() missing 2 required positional arguments: 'arg1' and 'arg2'

# this will ok
inspect.getcallargs(test_func, 1, 2, 3, a=1, b=2, c=3)
# {'kwargs': {'b': 2, 'c': 3, 'a': 1}, 'arg2': 2, 'args': (3,), 'arg1': 1}

应用场景

通过inspect.getcallargs的参数过滤功能,只要设置不同后台的authenticate的函数参数,就能在第一步实现不同角色的后台选择。

假设有三种角色,角色1使用用户名登录,角色2使用手机登录,角色3使用手机或者邮箱登录,那么如何通过inspect.getcallargs就选择合适的backend.authenticate呢?

def role3_authenticate(role3_phone=None, role3_email=None, password=None):
  print("role1 authentication.")

def role2_authenticate(role2_phone=None, password=None):
  print("role2 authenticate.")

def role1_authenticate(role1_name=None, password=None):
  print("role2 authenticate.")

methods = [role1_authenticate, role2_authenticate, role3_authenticate]
def authenticate(**credentials):
  for backend in methods:
    try:
      inspect.getcallargs(backend, **credentials)
    except TypeError:
      print("error")
      continue

    backend(**credentials)
    print("end")
    break

如果加入**kwargs则每个authenticate都不会引发TypeError,因为其余参数都设置了默认参数,如果确实需要,则之前的参数使用位置传参。

signal

若用户没有成功登陆,则authenticate发送了一个用户没有成功登陆的信号,开发者可以自行定义接受这个信号的recevier。关于django signal笔者之后还会详细谈及。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • PyTorch中torch.nn.Linear实例详解

    PyTorch中torch.nn.Linear实例详解

    torch.nn是包含了构筑神经网络结构基本元素的包,在这个包中可以找到任意的神经网络层,下面这篇文章主要给大家介绍了关于PyTorch中torch.nn.Linear的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)

    matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)

    这篇文章主要介绍了matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Pytorch使用卷积神经网络对CIFAR10图片进行分类方式

    Pytorch使用卷积神经网络对CIFAR10图片进行分类方式

    这篇文章主要介绍了Pytorch使用卷积神经网络对CIFAR10图片进行分类方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • python中for循环把字符串或者字典添加到列表的方法

    python中for循环把字符串或者字典添加到列表的方法

    今天小编就为大家分享一篇python中for循环把字符串或者字典添加到列表的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • Python批量提取PDF文件中文本的脚本

    Python批量提取PDF文件中文本的脚本

    这篇文章主要为大家详细介绍了Python批量提取PDF文件中文本的脚本,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例

    python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例

    这篇文章主要介绍了python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例,需要的朋友可以参考下
    2020-02-02
  • Python中的Dataset和Dataloader详解

    Python中的Dataset和Dataloader详解

    这篇文章主要介绍了Python中的Dataset和Dataloader详解,DataLoader与DataSet是PyTorch数据读取的核心,是构建一个可迭代的数据装载器,每次执行循环的时候,就从中读取一批Batchsize大小的样本进行训练,需要的朋友可以参考下
    2023-07-07
  • python进行图像边缘检测的详细教程

    python进行图像边缘检测的详细教程

    相信大家对于边缘检测这几个词并不陌生,但是相对于如何处理,如何进行图像的边缘检测却无能为力、束手无策了,下面这篇文章主要给大家介绍了关于python进行图像边缘检测的详细教程,需要的朋友可以参考下
    2023-04-04
  • python用Configobj模块读取配置文件

    python用Configobj模块读取配置文件

    这篇文章主要介绍了python用Configobj模块读取配置文件,帮助大家更好的利用python处理文件,感兴趣的朋友可以了解下
    2020-09-09
  • pygraphviz安装教程

    pygraphviz安装教程

    Graphviz 是一款由 AT&T Research 和 Lucent Bell 实验室开源的可视化图形工具,可以很方便的用来绘制结构化的图形网络,支持多种格式输出,这篇文章主要介绍了pygraphviz安装教程,需要的朋友可以参考下
    2023-02-02

最新评论