AberSheeran
Aber Sheeran

Python使用JWT

起笔自
所属文集: Python-Package
共计 1872 个字符
落笔于

最近在用阿里云的函数计算服务,需要使用JWK(Json Web Key)来生成JWT(Json Web Token),一时之间竟没有找到一个优雅的、提供JWK生成JWT的库,差点绝望的使用了阿里云给的Java样例。然后惊喜的发现PyJWT其实是支持JWK的,但是文档上并没有写。

此篇做一个系统的梳理,算是对官方文档的补充。

安装

如果你不需要使用类似于RSA的加密算法,那么正常的pipenv install pyjwt即可,否则应该使用pipenv install pyjwt[crypto]去安装(这会安装cryptography)。

一般使用

对称加密

常规使用JWT一般会使用对称加密进行签名,一是加解密速度相对快,二是密钥容易配置——随便一个字符串就行了。

以下为PyJWT官方文档例子:

>>> import jwt

>>> encoded_jwt = jwt.encode({'some': 'payload'}, 'SECRET', algorithm='HS256')
>>> encoded_jwt
'eyJhbGciOiJIU...'
>>> jwt.decode(encoded_jwt, 'SECRET', algorithms=['HS256'])
{'some': 'payload'}

其中SECRET就是需要保管的密钥,algorithm则指定了签名方法,algorithms指定验证签名时尝试使用的方法列表。

encodedecode的第一个参数就是需要进行签名的数据。

非对称加密

事实上常规使用非对称加密进行签名也很简单,自己生成一对密钥。

下面依旧是官方文档的例子:

>>> import jwt
>>> private_key = b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBS...'
>>> public_key = b'-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEAC...'
>>> encoded = jwt.encode({'some': 'payload'}, private_key, algorithm='RS256')
'eyJhbGciOiJIU...'
>>> decoded = jwt.decode(encoded, public_key, algorithms='RS256')
{'some': 'payload'}

除了注意验证签名时用公钥,签名时用私钥。写起来与对称加密签名没什么不同。

JWK使用

JWK是由RFC7517定义的格式。它一般是一个JSON对象。可以在 https://mkjwk.org/ 网站生成一对 JWK 对象。

from jwt.algorithms import RSAAlgorithm

RSAPublicKey = RSAAlgorithm.from_jwk(JWK-Public)
RSAPrivateKey = RSAAlgorithm.from_jwk(JWK-Private)

首先,分别使用JWK的公钥(JWK-Public)与私钥(JWK-Private)生成需要使用的公钥与私钥对象。注意,这里两者必须都是正确的JSON格式的字符串。

接下来的使用就如同常规的非对称加密方法一样了:

token = jwt.encode(data, key=RSAPrivateKey, algorithm='RS256')
data = jwt.decode(token, key=RSAPublicKey, algorithms="RS256")

在这里不得不吐槽一下,关于给PyJWT补充JWK的文档其实早有讨论,但是不知道为什么就不了了之了。快两年了吧,文档里还是没有介绍如何使用JWK。

如果你觉得本文值得,不妨赏杯茶
Django app配置子域名
Aligi