我正在使用python-jose的JWT实现生成JWT令牌以进行身份验证。
我们在Kubernetes的Docker容器中运行后端,有时候,当我们有多个pod时,我们会为相同的声明,机密和算法获取不同的令牌 。在touch
我的index.wsgi
脚本时,我的开发环境中的单个容器也发生了这种情况。
Pod 1:
>>> jwt.encode({'key': 'value'}, 'secret', algorithm='HS256')
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ2YWx1ZSJ9.FG-8UppwHaFp1LgRYQQeS6EDQF7_6-bMFegNucHjmWg'
Pod 2:
>>> jwt.encode({'key': 'value'}, 'secret', algorithm='HS256')
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJrZXkiOiJ2YWx1ZSJ9.JPIDicqvQ6GAh14yE2yZ3wnZQ0LiLNTTRDtJgLZcn98'
我深入研究了代码,看看是什么导致了这一点,并没有发现任何有罪的事情。简而言之,这就是代码的作用:
json.dumps
算法标题({'typ': 'JWT', 'alg': 'HS256'}
)并将其编码为Base64,删除所有=
的json.dumps
并将其编码为Base64,删除所有{'key': 'value'}
的=
密钥的HMAC256对encoded_header.encoded_payload
进行签名,并将其编码为Base64,再次删除任何secret
=
此时,我不知道造成这种情况的原因。我怀疑在HMAC或SHA256的Python实现中存在某种类型的错误,但这似乎不太可能......任何线索?
注意:我们已成功复制了encoded_header.encoded_payload.encoded_signature
的错误,pyjwt
是python-jose
的基础。
答案 0 :(得分:4)
这是因为Python词典是无序的。如果解码两个JWT,您将看到每个标记的标题部分的排序方式不同。
{
"typ": "JWT",
"alg": "HS256"
}
和
{
"alg": "HS256",
"typ": "JWT"
}
这会导致base64编码的标头不同,从而导致签名不同。
也就是说,这两个都是完全相同的索赔集的有效令牌,并且两者都应该成功验证。 JWT规范中没有任何内容规定等效的声明集应该导致等效的JWT输出。
注意:我是python-jose库的作者。