一. 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校验源码简析的更多相关文章

  1. SpringMVC学习(一)——概念、流程图、源码简析

    学习资料:开涛的<跟我学SpringMVC.pdf> 众所周知,springMVC是比较常用的web框架,通常整合spring使用.这里抛开spring,单纯的对springMVC做一下总 ...

  2. Flink源码阅读(一)——Flink on Yarn的Per-job模式源码简析

    一.前言 个人感觉学习Flink其实最不应该错过的博文是Flink社区的博文系列,里面的文章是不会让人失望的.强烈安利:https://ververica.cn/developers-resource ...

  3. 0002 - Spring MVC 拦截器源码简析:拦截器加载与执行

    1.概述 Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以进行权限验证.记录请求信息的日 ...

  4. OpenStack之Glance源码简析

    Glance简介 OpenStack镜像服务器是一套虚拟机镜像发现.注册.检索. glance架构图: Glance源码结构: glance/api:主要负责接收响应镜像管理命令的Restful请求, ...

  5. DRF之APIView源码简析

    一. 安装djangorestframework 安装的方式有以下三种,注意,模块就叫djangorestframework. 方式一:pip3 install djangorestframework ...

  6. AFNetworking源码简析

    AFNetworking基本是苹果开发中网络请求库的标配,它是一个轻量级的网络库,专门针对iOS和OS X的网络应用设计,具有模块化的架构和丰富的APIs接口,功能强大并且使用简单,深受苹果应用开发人 ...

  7. spring ioc源码简析

    ClassPathXmlApplicationContext 首先我们先从平时启动spring常用的ClassPathXmlApplicationContext开始解析 ApplicationCont ...

  8. 源码简析XXL-JOB的注册和执行过程

    一,前言 XXL-JOB是一个优秀的国产开源分布式任务调度平台,他有着自己的一套调度注册中心,提供了丰富的调度和阻塞策略等,这些都是可视化的操作,使用起来十分方便. 由于是国产的,所以上手还是比较快的 ...

  9. ElementUI 源码简析——源码结构篇

    ElementUI 作为当前运用的最广的 Vue PC 端组件库,很多 Vue 组件库的架构都是参照 ElementUI 做的.作为一个有梦想的前端(咸鱼),当然需要好好学习一番这套比较成熟的架构. ...

随机推荐

  1. ConxtMenu高级用法

    ##背景我们经常在列表的页面中,点击列表中的行,一般进入详情页面,长按列表中一行,会弹出一个菜单,包含了对某一行的操作(编辑.删除等等),也知道通常的用法: 0x01. 在Activity中注册需要上 ...

  2. OSX安装Mysql8.0

    OSX下MySQL的安装非常方便,可以通过官网的dmg包进行安装,也可通过brew进行安装.以下介绍如何通过brew如何安装MySQL. 0X00.安装前的准备 既然要通过brew安装,那么就需要确保 ...

  3. nginx 502排错

    线上一台机器(该论坛所在机器)近期频繁出现502,每100次访问就会出现10次,这频率也太高了.于是开始了我的502排查之旅 ps aux |grep -c php 结果为200 netstat -a ...

  4. 不同浏览器Cookie大小

    一.浏览器允许每个域名所包含的 cookie 数:Microsoft 指出 Internet Explorer 8 增加 cookie 限制为每个域名 50 个,但 IE7 似乎也允许每个域名 50 ...

  5. 神侃:反向激励能救活多少APP?

    ​ 在很多宣扬互联网企业成功的宣传文案中,为了将其包装地更大高大上和有逼格,总是会将各种心理学术名词用上,以显示自己对市场.用户群体的观察入微.当然事实上所谓的心理学术名词,都是"马后炮&q ...

  6. 在idea下遇到的问题汇总(间接性更新)

    在idea下遇到的问题汇总(间接性更新) tomcat下的jsp代码问题: 在idea的环境下,遇到jsp代码.符号失效,首先需要考虑到jar包没有引入,情况如图: 这种情况是因为jar包没有导入进去 ...

  7. 量化投资学习笔记34——《Python机器学习应用》课程笔记08

    岭回归 解决某些训练样本线性相关,导致回归结果不稳定的情况. 它是一种用于共线性数据分析的有偏估计回归方法.是一种改良的最小二乘估计法. 在sklearn中使用sklearn.linear_model ...

  8. volatile和synchronized到底啥区别?多图文讲解告诉你

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  9. 「ReStory」在 Markdown 中自由书写 React 组件 (Beta)

    介绍 先睹为快 我们在开发一个小小的 React 组件库,但是我们遇到了一个大难题,那就是为我们的组件库书写一个合理的文档. 作为组件文档,我们非常希望我们的组件用例代码能够展现出来,是的我们在书写文 ...

  10. elasticsearch 高级查询

    高级查询 子条件查询 (特定字段查询所指特定值) 复合条件查询 (以一定的逻辑组合子条件查询) 一.子条件查询 子条件查询分为 query context.filter context 1.query ...