JWT校验流程源码
一. 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
}

JWT校验流程源码的更多相关文章
- 【图解源码】Zookeeper3.7源码分析,包含服务启动流程源码、网络通信源码、RequestProcessor处理请求源码
Zookeeper3.7源码剖析 能力目标 能基于Maven导入最新版Zookeeper源码 能说出Zookeeper单机启动流程 理解Zookeeper默认通信中4个线程的作用 掌握Zookeepe ...
- [Android]从Launcher开始启动App流程源码分析
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5017056.html 从Launcher开始启动App流程源码 ...
- [Android]Android系统启动流程源码分析
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html Android系统启动流程源码分析 首先 ...
- Spring加载流程源码分析03【refresh】
前面两篇文章分析了super(this)和setConfigLocations(configLocations)的源代码,本文来分析下refresh的源码, Spring加载流程源码分析01[su ...
- Android Activity启动流程源码全解析(1)
前言 Activity是Android四大组件的老大,我们对它的生命周期方法调用顺序都烂熟于心了,可是这些生命周期方法到底是怎么调用的呢?在启动它的时候会用到startActivty这个方法,但是这个 ...
- Android Activity启动流程源码全解析(2)
接上之前的分析 ++Android Activity启动流程源码全解析(1)++ 1.正在运行的Activity调用startPausingLocked 一个一个分析,先来看看startPausing ...
- Spring IOC容器启动流程源码解析(四)——初始化单实例bean阶段
目录 1. 引言 2. 初始化bean的入口 3 尝试从当前容器及其父容器的缓存中获取bean 3.1 获取真正的beanName 3.2 尝试从当前容器的缓存中获取bean 3.3 从父容器中查找b ...
- 转:InnoDB Crash Recovery 流程源码实现分析
此文章转载给登博的文章,给大家分享 InnoDB Crash Recovery 流程源码实现分析 Crash Recovery问题 本文主要分析了InnoDB整个crash recovery的源码处理 ...
- Android笔记--View绘制流程源码分析(二)
Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...
随机推荐
- HTTP接口抓包工具之Fiddler
Fiddler的基本功能介绍: Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据,Fiddler包含了 ...
- Python---4字符串与编码
字符编码 字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个 ...
- 阿里凭啥比腾讯更会和Groupon相处好?
提起Groupon,大部分人对其第一反应就是那个"过气"的团购网鼻祖和与腾讯合作推出的国内团购网站"高朋网",死相极惨!虽然马化腾表示是双方准备不足的原因,但却 ...
- 使用Handler的步骤
使用Handler的大致流程: 1.首先创建一个Handler对象,可以直接使用Handler无参构造函数创建Handler对象,也可以继承Hander类,重写HandleMessage方法来创建Ha ...
- Java NIO-09-零拷贝之 DMA
DMA 的好处 在介绍DMA之前我想问大家:我们为什么要引入DMA,DMA对我们有什么好处那? 计算机系统中各种常用的数据输入/输出方法有查询方式(包括无条件及条件传送方式)和中断方式,这些方式适用于 ...
- 模拟HTTP请求超时时间设置
HTTP请求有两个超时时间:一个是连接超时时间,另一个是数据传输的最大允许时间(请求资源超时时间). 使用curl命令行 连接超时时间用 --connect-timeout 参数来指定 数据传输的最大 ...
- C++银行储蓄程序代码
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- sublime 安装Anaconda插件 配置python开发环境
我的sublime 3 python 3.6.6 安装Anaconda插件 由于Anaconda插件本身无法知道Python安装的路径,所以需要设置Python主程序的实际位置.选择Settings ...
- 拿到webshell之后的事情
之前搞站都是搞到后台管理员,或者搞到webshell就宣布结束了,,今天终于有机会学习一下后面的操作了. 公司网站为php的站,已经拿到webshell.可以进行菜刀连接. 菜刀虚拟终端 php -m ...
- MySql5.7.28下载、安装、登陆详解
进入MySql官网下载,页面如下 根据自己需求,选择适合自己的进行下载 然后解压安装包到自己的喜欢的路径 配置环境变量 添加环境系统变量 MYSQL_HOME:D:\Program Files\mys ...