django-jwt token校验源码简析
一. jwt token校验源码简析
1.1 前言
之前使用jwt签发了token,里面的头部包含了加密的方式、是否有签名等,而载荷中包含用户名、用户主键、过期时间等信息,最后的签名还使用了摘要算法进行不可逆的加密。
同时检验签名时还需进行签名的碰撞检测,判断该token是否合法。jwt提供了一个校验token的认证方法,使用时只需要CBV中进行局部身份验证配置即可。使用如下:
from rest_framework_jwt.authentication import JSONWebTokenAuthentication class 类名(JSONWebTokenAuthentication):
authentication_classes = [JSONWebTokenAuthentication]
不过自身的校验还存在一些缺陷,不能完全满足的需求,这时候我们可以继承该类后重写其中校验token的方法,具体是什么方法,我们接着往下看。
1.2 jwt的authenticate方法
以前走过APIView的源码,从源码得知身份校验走的是类中的authenticate的方法。定位至JSONWebTokenAuthentication,依据属性的查找顺序找到authenticate方法:
可以看出主要的方法是以上三个,接下来一一点进去瞅瞅(遵循属性查找顺序),首先是get_jwt_value(request)方法:


看看get_jwt_value中的get_authorization_header方法:

回到authenticate方法,此时jwt_value的值要么是None,要么是token:

再看看重点的校验token的方法jwt_decode_handler(jwt_value):



上述jwt.decode返回的载荷,有兴趣可以点进去看看源码,这里直接略过。
往下看看authenticate_credentials(payload)方法:

该函数返回一个user对象,最终由authenticate方法返回该user对象及token。不过试验时发现get_jwt_value方法返回的是None而不是token时,authenticate方法return None,这时也能通过校验,所以我们可以重写authenticate方法,对get_jwt_value中用于取头部token信息的get_authorization_header返回的值进行判断,增加健壮性。
import jwt
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.authentication import get_authorization_header
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
def authenticate(self, request):
# 采用drf获取token的手段 - HTTP_AUTHORIZATION - Authorization
token = get_authorization_header(request)
if not token:
raise AuthenticationFailed('Authorization 字段是必须的')
# 可以添加反扒措施:原功能是token有前缀 # drf-jwt认证校验算法
try:
payload = jwt_decode_handler(token)
except jwt.ExpiredSignature:
raise AuthenticationFailed('签名过期')
except jwt.InvalidTokenError:
raise AuthenticationFailed('非法用户')
user = self.authenticate_credentials(payload)
# 将认证结果丢该drf
return user, token
AUTHENTICATION_BACKENDS = ['user.utils.JWTModelBackend']
二. jwt的RefreshJSONWebToken
jwt生成token后,因为token有个过期时间,而这个时间默认是五分钟,之后客户端携带token重新访问时,会调用jwt的RefreshJSONWebToken中的RefreshJSONWebTokenSerializer类中的validate方法,来刷新客户端的token,而刷新的时间也是有上限的,默认是七天,可以在项目下的配置中自定义。
# 配置的默认过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300) # token刷新的最大时间间隔,默认七天
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7)
如自定义过期时间:
import datetime
JWT_AUTH = {
# 过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}
接下来看看RefreshJSONWebTokenSerializer的源码。

让我们看看validate方法:



validate方法源码如下:
def validate(self, attrs):
token = attrs['token'] payload = self._check_payload(token=token)
user = self._check_user(payload=payload)
# Get and check 'orig_iat'
orig_iat = payload.get('orig_iat') if orig_iat:
# Verify expiration
refresh_limit = api_settings.JWT_REFRESH_EXPIRATION_DELTA if isinstance(refresh_limit, timedelta):
refresh_limit = (refresh_limit.days * 24 * 3600 +
refresh_limit.seconds) expiration_timestamp = orig_iat + int(refresh_limit)
now_timestamp = timegm(datetime.utcnow().utctimetuple()) if now_timestamp > expiration_timestamp:
msg = _('Refresh has expired.')
raise serializers.ValidationError(msg)
else:
msg = _('orig_iat field is required.')
raise serializers.ValidationError(msg) new_payload = jwt_payload_handler(user)
new_payload['orig_iat'] = orig_iat return {
'token': jwt_encode_handler(new_payload),
'user': user
}
django-jwt token校验源码简析的更多相关文章
- SpringMVC学习(一)——概念、流程图、源码简析
学习资料:开涛的<跟我学SpringMVC.pdf> 众所周知,springMVC是比较常用的web框架,通常整合spring使用.这里抛开spring,单纯的对springMVC做一下总 ...
- Flink源码阅读(一)——Flink on Yarn的Per-job模式源码简析
一.前言 个人感觉学习Flink其实最不应该错过的博文是Flink社区的博文系列,里面的文章是不会让人失望的.强烈安利:https://ververica.cn/developers-resource ...
- 0002 - Spring MVC 拦截器源码简析:拦截器加载与执行
1.概述 Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以进行权限验证.记录请求信息的日 ...
- OpenStack之Glance源码简析
Glance简介 OpenStack镜像服务器是一套虚拟机镜像发现.注册.检索. glance架构图: Glance源码结构: glance/api:主要负责接收响应镜像管理命令的Restful请求, ...
- DRF之APIView源码简析
一. 安装djangorestframework 安装的方式有以下三种,注意,模块就叫djangorestframework. 方式一:pip3 install djangorestframework ...
- AFNetworking源码简析
AFNetworking基本是苹果开发中网络请求库的标配,它是一个轻量级的网络库,专门针对iOS和OS X的网络应用设计,具有模块化的架构和丰富的APIs接口,功能强大并且使用简单,深受苹果应用开发人 ...
- spring ioc源码简析
ClassPathXmlApplicationContext 首先我们先从平时启动spring常用的ClassPathXmlApplicationContext开始解析 ApplicationCont ...
- 源码简析XXL-JOB的注册和执行过程
一,前言 XXL-JOB是一个优秀的国产开源分布式任务调度平台,他有着自己的一套调度注册中心,提供了丰富的调度和阻塞策略等,这些都是可视化的操作,使用起来十分方便. 由于是国产的,所以上手还是比较快的 ...
- ElementUI 源码简析——源码结构篇
ElementUI 作为当前运用的最广的 Vue PC 端组件库,很多 Vue 组件库的架构都是参照 ElementUI 做的.作为一个有梦想的前端(咸鱼),当然需要好好学习一番这套比较成熟的架构. ...
随机推荐
- python socket粘包及实例
1.在linux中经常出现粘包的出现(因为两个send近靠着,造成接受到的数据是在一起的.)解决方法: 在服务端两send的中间中再添加一个recv(),客户端添加一个send(),服务端收到信息确认 ...
- Jmeter运行不显示cmd对话框
1.Jmeter运行不显示cmd对话框 如图所示,在Jmeter的bin目录下新建一个vbs的脚本,脚本内容为: Dim wsh Set wsh=WScript.CreateObject(" ...
- Docker系列之实战:3.安装MariaDB
环境 [root@centos181001 ~]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core) [root@centos1 ...
- frp端口映射穿透内网
前言 frp 是一个高性能的反向代理应用,可以轻松地进行内网穿透,对外网提供服务,支持 TCP.UDP.HTTP.HTTPS 等协议类型,并且 web 服务支持根据域名进行路由转发. Github: ...
- 学习HEXO的历程
前言: 简介 开始搭建 命令 API测试 逛github相关的帖子时,发现了hexo.正好想要做一个个人的博客,用来记录自己的各类感悟,所以花一些时间学习学习,以后博客可以放github,省得去注册c ...
- DIY电压基准测万用表
| 分类 日志 | 手里有三个常用的手持表,UT61E四位半,优利德明星产品:福禄克F117C,换挡快,单手操作还带LoZ:UT210E小钳表能够通过修改EEPROM更改电表配置,已经刷了6000字 ...
- 沈向洋|微软携手 OpenAI 进一步履行普及且全民化人工智能的使命
OpenAI 进一步履行普及且全民化人工智能的使命"> 作者简介 沈向洋,微软全球执行副总裁,微软人工智能及微软研究事业部负责人 我们正处于技术发展历程中的关键时刻. 云计算的强大计算 ...
- CSS——NO.6(盒模型)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- 02ARM体系结构
1.哈佛结构和冯式结构 8086: 冯氏结构 相同存储RAM相同的通道 统一编址 区别:运行态与存储态 STM32F103:哈弗结构 不同的存储不同的通道 统一编址 8051: 改进型的哈弗结构 不 ...
- Java大浮点数精度
BigDecimal 精度问题 BigDecimal舍入模式 ROUND_DOWN 向零舍入. 即1.55 变为 1.5 , -1.55 变为-1.5 ROUND_UP 向远离0的方向舍入 即 1.5 ...