一. 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. numpy创建的array

    import numpy as np array = np.array([[1,2,3], [2,3,4]]) #打印列表 print(array)#是几维的 print('number of dim ...

  2. 常用JS代码片段

    1.隐藏部分数字,如手机号码,身份证号码 1 2 3 function (str,start,length,mask_char){ return str.replace(str.substr(star ...

  3. 【pic+js+gh】免费高速图床方案

    本文用到的工具或网站 PicGo jsdelivr github 速度对比 Github的速度: jsdelivrCDN的速度: 下载PicGo 首先进入PicGo的下载地址 选择最新版本下载,根据自 ...

  4. Web 通信技术 ——跨文档信息传输(JavaScript)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.html * 作者:常轩 * 微信公众号:Worldh ...

  5. IP 数据报

    IP 数据报 1.IP 数据报的格式 一个 IP 数据报由首部和数据两部分组成.(数据报也可以说是数据包) 首部的前一部分是固定长度,共 20 字节,是所有 IP 数据报必须具有的. 在首部的固定部分 ...

  6. 我去,你写的 switch 语句也太老土了吧

    昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意.但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:& ...

  7. node--fs

    1.fs模块内置方法 1)stat 检测是文件还是目录 fs.stat(fileAddress,(err,stats)=>{ //err 出错信息 //stats.isFile() 该东西是文件 ...

  8. 移动端轮播图实现方法(dGun.js)

    本文章介绍在移动端无缝隙轮播图实现的原理,这个轮子比较简单,但可以方便刚刚入门的同学参考.最终效果是在移动端无缝隙无限滑动,可以自定义轮播的速度.支持手势左右滑动.最后会放上源码. HTML部分 &l ...

  9. 关于 InnoDB 锁的超全总结

    有点全的 InnoDB 锁 几个月之前,开始深入学习 MySQL .说起数据库,并发控制是其中很重要的一部分.于是,就这样开起了 MySQL 锁的学习,随着学习的深入,发现想要更好的理解锁,需要了解 ...

  10. 关于在layui中的table checkbox 默认选中设置

    一.layui版本 layui-v2.4.5 二.设置table的checkbox默认选中 总共有两种方法: 方法1:在返回的json中设置LAY_CHECKED为true,页面上的checkbox就 ...