栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

基于Django的JWT实现

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于Django的JWT实现

JWT流程

传统session鉴权:

以Django的账号密码登录为例来说明传统的验证鉴权方式是怎么工作的,当我们登录页面输入账号密码提交表单后,会发送请求给服务器,服务器对发送过来的账号密码进行验证鉴权,验证鉴权通过后,把用户信息记录在服务器端(django_session表中),同时返回给浏览器一个sessionid用来唯一标识这个用户,浏览器将sessionid保存在cookie中,之后浏览器的每次请求都一并将sessionid发送给服务器,服务器根据sessionid与记录的信息做对比以验证身份

Token鉴权

Token的鉴权方式就清晰很多了,客户端用自己的账号密码进行登录,服务端验证鉴权,验证鉴权通过生成Token返回给客户端,之后客户端每次请求都将Token放在header里一并发送,服务端收到请求时校验Token以确定访问者身份

使用场景

  • session的主要目的是给无状态的HTTP协议添加状态保持,通常在浏览器作为客户端的情况下比较通用。
  • 而Token的主要目的是为了鉴权,同时又不需要考虑CSRF防护以及跨域的问题,所以更多的用在专门给第三方提供API的情况下。
  • 客户端请求无论是浏览器发起还是其他的程序发起都能很好的支持。所以目前基于Token的鉴权机制几乎已经成了前后端分离架构或者对外提供API访问的鉴权标准,得到广泛使用。
json web token的结构

jwt的结构由三个部分组成:

  • Header(头部):定义token类型和加密方式
  • Payload(数据):定义具体内容,如用户名,发行时间,过期时间等
  • Signature(签名)
header头的格式如下
headers = {
        #typ 属性表示令牌类型,这里就是 JWT。
       'typ': ' jwt',		
        # alg 属性表示签名所使用的算法,JWT 签名默认的算法为 HMAC SHA256 , alg 属性值 HS256 就是 HMAC SHA256 算法
        'alg': 'HS256'
        }
Payload的格式
#常用格式
payload = {
	iss:jwt的签发者/发行人;
	
	sub:主题;
	
	aud:接收方;
	
	exp:jwt过期时间;
	
	nbf:jwt生效时间;
	
	iat:签发时间
	
	jti:jwt唯一身份标识,可以避免重放攻击
}
#也可以不必遵循,例:
payload = {
    'userid': userid,        #用户表id
    'user_code': username    #用户名
}

Signature格式
#这是对前边header和payload进行签名,以后在发送/接收消息时,如果在数据被更改,则这段token值会变化,可以在每次传送数据时,判断该token是否被修改,由此判断数据是否安全
token = jwt.encode(payload=payload, key=salt, algorithm='HS256', headers=headers).decode('utf-8')
PyJWT原理解析

利用PyJWT生成Token

In [1]: import jwt

In [2]: encoded_jwt=jwt.encode({"username":"knight"},"ak",algorithm='HS256')


这里传了三部分内容给JWT,

  • 第一部分是一个Json对象,称为Payload,主要用来存放有效的信息,例如用户名,过期时间等等所有你想要传递的信息
  • 第二部分是一个秘钥字串,这个秘钥主要用在下文Signature签名中,服务端用来校验Token合法性,这个秘钥只有服务端知道,不能泄露
  • 第三部分指定了Signature签名的算法
#  查看生成的token
In [3]: print(encoded_jwt)
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImtuaWdodCJ9.vkNT0MVrdW5GJhzPLEtVBqGteqEQAMpW9rBH_SDQSP8

JWT生成的Token是一个用两个点(.)分割的长字符串

点分割成的三部分分别是Header头部,Payload负载,Signature签名:

Header.Payload.Signature

JWT是不加密的,任何人都可以读的到其中的信息。

  • 其中第一部分Header和
  • 第二部分Payload只是对原始输入的信息转成了base64编码,
  • 第三部分Signature是用header+payload+secret_key进行加密的结果

可以直接用base64对 Header 和 Payload进行解码得到相应的信息。

## 
In [4]: import base64

In [5]: base64.b64decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9')
Out[5]: b'{"typ":"JWT","alg":"HS256"}'

因为JWT不会对结果进行加密,所以不要保存敏感信息在Header或者Payload中,服务端也主要依靠最后的Signature来验证Token是否有效以及有无被篡改

解密Token

In [7]: jwt.decode(encoded_jwt,'ak',algorithms=['HS256'])
Out[7]: {'username': 'knight'}
JWT实践

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/934168.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号