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生成), ...
随机推荐
- Catalan数应用问题
- Thomson Plaza里面的三家店以及水果大会
旅行应该是一个发现的过程,至少我是这么认为的.很多时候并不一定要到什么特别的地方,也可以感受到旅游的乐趣.我觉得只要能看到值得回味的东西就好了.而能回味的东西,往往是需要仔细地来品.像旅行社安排的那样 ...
- HBase源码系列之HFile
本文讨论0.98版本的hbase里v2版本.其实对于HFile能有一个大体的较深入理解是在我去查看"到底是不是一条记录不能垮block"的时候突然意识到的. 首先说一个对HFile ...
- C++扬帆远航——10(求π)
/* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:π.cpp * 作者:常轩 * 微信公众号:Worldhello ...
- LeetCode--二叉树1--树的遍历
LeetCode--二叉树1--树的遍历 一 深度遍历 深度遍历里面由 三种遍历方式,两种实现方法.都要熟练掌握. 值得注意的是,当你删除树中的节点时,删除过程将按照后序遍历的顺序进行. 也就是说,当 ...
- linux入门系列17--邮件系统之Postfix和Dovecot
前文演示了通过Samba和NFS实现文件共享,本篇演示使用Postfix和Dovecot在局域网实现电子邮件收发系统. 电子邮件系统是我们日常生活和工作中非常重要的一个网络服务,在windows下收发 ...
- iOS内存区域分布
概览 1,RAM ROM 2,内存的几大区域 3,案例解释 RAM ROM RAM:运行内存,不能掉电存储. ROM:存储性内存,可以掉电存储,例如内存卡.Flash. 内存的几大区域 为了合理的分配 ...
- 记一次苹果APP从账号续费到发布成功的历程
一.一波三折的续费 最近公司开发的苹果APP的SSL证书到期了,计划重新发布一下该APP,已替换即将到期的SSL证书.近几年随着钉钉.企业微信等在线办公软件超级平台的出现,各企业都会选择其中 ...
- Maven项目中的packaging标签
<packaging>XXX</packaging> 项目的打包类型xxx:pom.jar.war.(packing默认是jar类型). pom是最简单的打包类型,pom 项目 ...
- 微信小程序学习简介
如何向微信小程序导入DEMO源码: 参考方法 参考学习小程序官方文档 小程序官方文档 小程序目录简介 app.json :设置一些工程全局的量.js : 写一些函数逻辑.wxml: 调用.js中写的函 ...