authenticate验证的流程
流程简单梳理
- - 入口
- from django.contrib.auth import authenticate
- user = authenticate(username=cd['username'], password=cd['password'])
- # If the given credentials are valid, return a User object.
- - 获取全部用于认证的backend
- settings.AUTHENTICATION_BACKENDS
- Default: ['django.contrib.auth.backends.ModelBackend']
- # https://docs.djangoproject.com/en/1.11/ref/settings/#auth
- - 遍历全部backend并执行认证操作
- user = _authenticate_with_backend(backend, backend_path, request, credentials)
- # credentials: { 'username':'xxx', 'password':'xxx' }
- 默认只有ModelBackend这个backend,认证是通过调用这个类里的authenticate函数
- - 通过username查找出user对象
- - user.check_password(password)
- # django.contrib.auth.base_user.AbstractBaseUser
- - AbstractBaseUser.check_password(self, raw_password)
- - django.contrib.auth.hashers.check_password(raw_password, self.password, setter)
- - 获取settings.PASSWORD_HASHERS里的第一个hash算法
- 默认是 django.contrib.auth.hashers.PBKDF2PasswordHasher
- - 根据self.password来找到当前用户的密码采用的hash算法
- - 判断用户密码采用的hash算法和当前默认的第一hash算法是否相同 (暂且只考虑相同的情况)
- - 把用户密码拆分成:algorithm, iterations, salt, hash,用iterations和hash算法的iterations做对比是否一致
- - 验证:hasher.verify(password, encoded)
- - 把用户输入的密码进行加密:先用hashlib.sha256,然后在用base64.b64encode最终计算出一个hash值
- - 然后把 self.algorithm, iterations, salt, hash 组合成一个字符串,记作encoded_2
- - 把用户真实密码和encoded_2作比较,看看是否相同
- - user_can_authenticate(user)
- - 判断当前用户的 is_active
from django.contrib.auth import authenticate
# 默认的第一个加密算法
- class PBKDF2PasswordHasher(BasePasswordHasher):
- """
- Secure password hashing using the PBKDF2 algorithm (recommended)
- Configured to use PBKDF2 + HMAC + SHA256.
- The result is a 64 byte binary string. Iterations may be changed
- safely but you must rename the algorithm if you change SHA256.
- """
- algorithm = "pbkdf2_sha256"
- iterations = 36000
- digest = hashlib.sha256
- def encode(self, password, salt, iterations=None):
- assert password is not None
- assert salt and '$' not in salt
- if not iterations:
- iterations = self.iterations
- hash = pbkdf2(password, salt, iterations, digest=self.digest)
- hash = base64.b64encode(hash).decode('ascii').strip()
- return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
- def verify(self, password, encoded):
- algorithm, iterations, salt, hash = encoded.split('$', 3)
- assert algorithm == self.algorithm
- encoded_2 = self.encode(password, salt, int(iterations))
- return constant_time_compare(encoded, encoded_2)
- def safe_summary(self, encoded):
- algorithm, iterations, salt, hash = encoded.split('$', 3)
- assert algorithm == self.algorithm
- return OrderedDict([
- (_('algorithm'), algorithm),
- (_('iterations'), iterations),
- (_('salt'), mask_hash(salt)),
- (_('hash'), mask_hash(hash)),
- ])
- def must_update(self, encoded):
- algorithm, iterations, salt, hash = encoded.split('$', 3)
- return int(iterations) != self.iterations
- def harden_runtime(self, password, encoded):
- algorithm, iterations, salt, hash = encoded.split('$', 3)
- extra_iterations = self.iterations - int(iterations)
- if extra_iterations > 0:
- self.encode(password, salt, extra_iterations)
from django.contrib.auth.hashers import make_password
- def make_password(password, salt=None, hasher='default'):
- """
- Turn a plain-text password into a hash for database storage
- Same as encode() but generates a new random salt.
- If password is None then a concatenation of
- UNUSABLE_PASSWORD_PREFIX and a random string will be returned
- 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)
from django.contrib.auth.hashers import check_password
- def check_password(password, encoded, setter=None, preferred='default'):
- """
- Returns a boolean of whether the raw password matches the three
- part encoded digest.
- If setter is specified, it'll be called when you need to
- regenerate the password.
- """
- if password is None or not is_password_usable(encoded):
- return False
- preferred = get_hasher(preferred)
- hasher = identify_hasher(encoded)
- hasher_changed = hasher.algorithm != preferred.algorithm
- must_update = hasher_changed or preferred.must_update(encoded)
- is_correct = hasher.verify(password, encoded)
- # If the hasher didn't change (we don't protect against enumeration if it
- # does) and the password should get updated, try to close the timing gap
- # between the work factor of the current encoded password and the default
- # work factor.
- if not is_correct and not hasher_changed and must_update:
- hasher.harden_runtime(password, encoded)
- if setter and is_correct and must_update:
- setter(password)
- return is_correct
authenticate在处理用户登录验证时候的过程
- import os
- os.environ.setdefault('DJANGO_SETTINGS_MODULE','django_auth.settings')
- from django.contrib.auth.hashers import (
- check_password, is_password_usable, make_password,
- )
- if __name__ == '__main__':
- raw_password = 'Qr3!JQc9bU@hrs2qjdqaE'
- password = make_password(raw_password)
- print(password)
- from django.conf import settings
- # print(settings.AUTHENTICATION_BACKENDS) # django.contrib.auth.backends.ModelBackend
- from django.utils.module_loading import import_string
- # for backend_path in settings.AUTHENTICATION_BACKENDS:
- # backend = import_string(backend_path)()
- # print(backend_path,backend)
- hashers_lst = settings.PASSWORD_HASHERS
- '''
- [
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.Argon2PasswordHasher',
- 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
- 'django.contrib.auth.hashers.BCryptPasswordHasher']
- '''
- preferred = import_string(hashers_lst[0])()
- # <django.contrib.auth.hashers.PBKDF2PasswordHasher object at 0x0000000000B3BAC8>
- print(preferred.algorithm)
- from django.contrib.auth import hashers
- encoded = 'pbkdf2_sha256$36000$0EDgzLtVVT7o$nWQ4t3+iWKzv9p6MUfNIQPazaasadhYUtKt2ubLRCTA='
- hasher = hashers.identify_hasher(encoded)
- # <django.contrib.auth.hashers.PBKDF2PasswordHasher object at 0x0000000000BB8978>
- print(hasher.algorithm) # pbkdf2_sha256
- hasher_changed = hasher.algorithm != preferred.algorithm
- print(hasher_changed) # False
- is_correct = hasher.verify(raw_password, encoded)
- print(is_correct)
- algorithm, iterations, salt, hash = encoded.split('$', 3)
- print(algorithm, iterations, salt, hash)
- encoded2 = hasher.encode(raw_password, salt, int(iterations))
- print(encoded2)
看源码,打印输出,是接近真相最便捷的途径。
authenticate验证的流程的更多相关文章
- https申请证书并部署到网站流程,浏览器验证证书流程
https申请证书并部署到网站流程: 1.生成一对秘钥,设公钥为pubk1,私钥为prik12.假设发布的网站地址为https://www.example.com3.生成一个CSR文件(Cerific ...
- Token验证的流程及如何准确的判断一个数据的类型
Token验证的流程: 1,客户端使用用户名跟密码请求登录:2,服务端收到请求,去验证用户名与密码:3,验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端:4,客户端收到 T ...
- authenticate的执行流程与重写
流程 1.authenticate调用的是_get_backends函数 def authenticate(request=None, **credentials): for backend, bac ...
- springcloud +spring security多种验证方式之第三方token生成自己的token通过校验和自己的表单验证大体流程
步骤: 1.继承 WebSecurityConfigurerAdapter.class,其中使用两个过滤器,一个spring scurity自带的UsernamePasswordAuthenticat ...
- Shiro -- (二) 身份验证基本流程
简介: 在 shiro 中,用户需要提供 principals (身份)和 credentials(证明)给 shiro,从而应用能验证用户身份: principals:身份,即主体的标识属性,可以是 ...
- Apache shiro之身份验证(登陆)流程
从张开涛blog学习后整理:http://jinnianshilongnian.iteye.com/blog/2018398 上图中的类和接口都可以继承和实现来个性化自己的实现. 其中重点看一下Mod ...
- SharePoint2010 Form验证配置流程
1.修改管理中心的Web.config文件,位置:C:\inetpub\wwwroot\wss\VirtualDirectories\42903 2.修改应用程序的Web.config文件,位置:C: ...
- 【ASP.NET】编程点滴 :ASP.NET身份验证
ASP.NET实际开发中身份验证 是一个不可回避的问题.在相当一段长的时间内,由于不求甚解,我对这个话题似懂非懂.今天就对它做个简单的小结. Authentication and Authorizat ...
- ASP.NET Forms身份验证概述
表单身份验证允许您使用自己的代码对用户进行身份验证,然后在cookie或页面URL中维护身份验证令牌.表单身份验证通过FormsAuthenticationModule类参与ASP.NET页面生命周期 ...
随机推荐
- 自定义Qt构建步骤,添加数据文件(txt,json等)到构建目录
Qt的qrc资源文件是只读的,因此我们如果要用txt之类的文件存储数据,在程序运行过程中就不能对它们进行修改,也就是不能进行读操作.用"file.open(QIODevice::WriteO ...
- 使用nmon监控Linxu服务器性能
nmon是IBM开发的Linux软件工具.能够监控多项Linux服务,最常见的如:CPU使用率.内存使用率.硬盘读写.网卡流量等. 并能设置参数,将记录的数据保存到文件,利用Excel做统计分析. 安 ...
- 洛谷P5069 [Ynoi2015]纵使日薄西山(树状数组,set)
洛谷题目传送门 一血祭 向dllxl致敬! 算是YNOI中比较清新的吧,毕竟代码只有1.25k. 首先我们对着题意模拟,寻找一些思路. 每次选了一个最大的数后,它和它周围两个数都要减一.这样无论如何, ...
- Centos 7.3 安装Grafana 6.0
grafana简介 Grafana是一个完全开源的度量分析与可视化平台,可对来自各种各种数据源的数据进行查询.分析.可视化处理以及配置告警. Grafana支持的数据源: 官方:Graphite,In ...
- 【转】gcc 编译使用动态链接库和静态链接库
1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...
- 如何 通过 userAgent 区别微信小程序
微信内置浏览器: 微信小程序: 有micromessenger是微信内置浏览器,有micromessenger和miniprogram的是微信小程序. (ios不适用) if(navigator.u ...
- HDU/HDOJ 4699 Editor
对顶栈算法. 此题充分说明了cin的不中以及scanf的优越性. 我TM用cin超时了!!!换成scanf就A了!!! #include <cstdio> #include <cst ...
- tyvj/joyoi 1340 送礼物
论搜索顺序的优越性. 从小到大搜索,T到怀疑人生. 从大到小搜索,轻松AC. 双向搜索. 是这样的.我们首先排序一下,然后翻转.(当然也可以写cmp) 然后我们搜前半部分,把结果记录在某一数组中. 然 ...
- 【Asia Yokohama Regional Contest 2018】Arithmetic Progressions
题目大意:给定 N(1<N<=5000) 个不同元素组成的集合,求从中选出若干数字组成的等差数列最长是多少. 题解:直接暴力有 \(O(n^3)\) 的算法,即:枚举等差数列的前两个值,再 ...
- django2 用iframe标签完成 网页内嵌播放b站视频功能
前言: 给自己的网站中加入视频资源,有两种方法,一种是用iframe标签引用外站资源,另一种则使用video标签,获取站内资源进行视频播放.其中前者顾名思义,是将视频资源上传到视频网站中,然后通过引用 ...