我正在使用 python-jose的 JWT 实现以生成用于身份验证目的的 JWT token 。
我们在 Kubernetes 上的 Docker 容器中运行后端,有时,当我们有多个 pod 时,我们会为相同的声明、 secret 和算法获得不同的 token .当 touch
我的 index.wsgi
脚本时,我的开发环境中的单个容器也发生过这种情况。
连播机 1:
>>> jwt.encode({'key': 'value'}, 'secret', algorithm='HS256')
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ2YWx1ZSJ9.FG-8UppwHaFp1LgRYQQeS6EDQF7_6-bMFegNucHjmWg'
连播机 2:
>>> jwt.encode({'key': 'value'}, 'secret', algorithm='HS256')
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJrZXkiOiJ2YWx1ZSJ9.JPIDicqvQ6GAh14yE2yZ3wnZQ0LiLNTTRDtJgLZcn98'
我深入研究了代码,看看是什么导致了这种情况,但没有发现任何有罪的地方。简而言之,代码的作用如下:
- 对算法 header (
{'typ': 'JWT', 'alg': 'HS256'}
) 执行json.dumps
并将其编码为 Base64 , 删除任何=
的 - 对有效负载 (
{'key': 'value'}
) 执行json.dumps
并将其编码为 Base64,删除任何=
的 - 使用 HMAC256 和
secret
key 对encoded_header.encoded_payload
进行签名,并将其编码为 Base64,再次删除所有=
的 - 将签名连接到前面的字符串,得到
encoded_header.encoded_payload.encoded_signature
此时,我不知道是什么原因造成的。我怀疑 Python 的 HMAC 或 SHA256 实现中存在某种错误,但这似乎不太可能……有什么线索吗?
注意:我们已经使用 pyjwt
成功重现了这个错误,它是 python-jose
的基础。
最佳答案
这是因为 Python 字典是无序的。如果您对这两个 JWT 进行解码,您将看到每个 token 的 header 部分的顺序不同。
{
"typ": "JWT",
"alg": "HS256"
}
和
{
"alg": "HS256",
"typ": "JWT"
}
这会导致 base64 编码的 header 不同,进而导致签名不同。
也就是说,这两个都是完全相同的声明集的有效标记,并且都应该成功验证。 JWT 规范中没有任何内容规定等效的声明集应产生等效的 JWT 输出。
注意:我是 python-jose 的作者图书馆。
关于python - 不同的服务器使用相同的参数生成不同的 JWT token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43351439/