- 关于 jwt 的原理及概念可以自行在网络上搜索了解一下,这里推荐一篇写的比较好的博客
另附 JWT 的官方文档: https://jwt.io/introduction/
python 对于 jwt 的实现, 目前已经存在了一些第三方的库, 相信学习过 python 的程序猿都知道 itsdangerous 这个库了, 它的底层原理就是基于 jwt 进行实现的
python实现生成 json web token
环境: python3.6.7
依赖包: jwt, time
1)JWT 的签名算法有三种。
1.对称加密HMAC【哈希消息验证码】 HS256/HS384/HS512
这种加密方式没有公钥,私钥之分, 也就是只有一个密钥, 这种加密方式适用于: 服务器将生成的jwt发送给接收方, 接收方将其返回给服务器, 服务器解析 jwt, 完成身份验证.
2.非对称加密RSASSA【RSA签名算法】RS256/RS384/RS512
3.ECDSA【椭圆曲线数据签名算法】 ES256/ES384/ES512
2).对称加密HMAC 生成 jwt
import time
import jwt
# payload
token_dict = {
'iat':time.time(), # 时间戳
'name':'George'
}
"""payload 中一些固定参数名称的意义, 同时可以在payload中自定义参数"""
# iss 【issuer】发布者的url地址
# sub 【subject】该JWT所面向的用户,用于处理特定应用,不是常用的字段
# aud 【audience】接受者的url地址
# exp 【expiration】 该jwt销毁的时间;unix时间戳
# nbf 【not before】 该jwt的使用时间不能早于该时间;unix时间戳
# iat 【issued at】 该jwt的发布时间;unix 时间戳
# jti 【JWT ID】 该jwt的唯一ID编号
# headers
headers = {
'alg': "HS256", # 所使用的加密算法方式
'kid': "8888", # key_id
}
"""headers 中一些固定参数名称的意义"""
# jku: 发送JWK的地址;最好用HTTPS来传输
# jwk: 就是之前说的JWK
# kid: jwk的ID编号
# x5u: 指向一组X509公共证书的URL
# x5c: X509证书链
# x5t:X509证书的SHA-1指纹
# x5t#S256: X509证书的SHA-256指纹
# typ: 在原本未加密的JWT的基础上增加了 JOSE 和 JOSE+ JSON。JOSE序列化后文会说及。适用于JOSE标头的对象与此JWT混合的情况。
# crit: 字符串数组,包含声明的名称,用作实现定义的扩展,必须由 this->JWT的解析器处理。不常见。
# 调用jwt库,生成json web token
jwt_token = jwt.encode(token_dict, # payload, 有效载体
"George8888", # 进行加密签名的密钥
algorithm="HS256", # 指明签名算法方式, 默认也是HS256
headers=headers # json web token 数据结构包含两部分, payload(有效载体), headers(标头)
).decode('ascii') # python3 编码后得到 bytes, 再进行解码(指明解码的格式), 得到一个str
print(jwt_token)
# 个人测试生成结果如下: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijg4ODgifQ.eyJpYXQiOjE1NjQwMjU0MTcuNTc1NDQ3LCJuYW1lIjoiR2VvcmdlIn0.ScPOppgmV3wM-o8ohVL4u2mUGPql5-cwaOO8ZvLn4jM
- 使用 python 对 jwt 进行解析
import jwt
# 将上面生成的 jwt 进行解析认证
jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ijg4ODgifQ.eyJpYXQiOjE1NjQwMjU0MTcuNTc1NDQ3LCJuYW1lIjoiR2VvcmdlIn0.ScPOppgmV3wM-o8ohVL4u2mUGPql5-cwaOO8ZvLn4jM"
data = None
try:# 需要解析的 jwt 密钥 使用和加密时相同的算法
data = jwt.decode(jwt_token, "George8888", algorithms=['HS256'])
except Exception as e:# 如果 jwt 被篡改过; 或者算法不正确; 如果设置有效时间, 过了有效期; 或者密钥不相同; 都会抛出相应的异常
print(e)
# 解析出来的就是 payload 内的数据
print(data)
# 输出: {'iat': 1564025417.575447, 'name': 'George'}
4)如果是使用私钥公钥进行加密解密的方式(由请求方使用私钥进行加密生成 jwt, 接收方使用公钥解密), 只需要将相应参数更换成私钥(将私钥证书读取出来, 赋值给相应参数即可), 并使用双方约定好的的签名算法
- python 对于 jwt 的实现, 已经有了 itsdangerous 这个库做了很好的支撑, 使用起来还是很方便的, 大家可以自行去了解一下.
itsdangerous 官方文档: https://itsdangerous.readthedocs.io/en/1.1.x/