不同的服务器使用相同的参数生成不同的JWT令牌
我正在使用python-jose的JWT实现来生成用于身份validation目的的JWT令牌。
我们在Kubernetes的Docker容器中运行我们的后端, 有时,当我们有多个Pod时,我们为相同的声明,秘密和algorithm获得不同的令牌 。 在touch
我的index.wsgi
脚本时,我的开发环境中也发生过这种情况。
豆荚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
的algorithm头({'typ': 'JWT', 'alg': 'HS256'}
),并将其编码为Base64,删除任何=
's - 做一个有效载荷的
json.dumps
({'key': 'value'}
)并将其编码为Base64,删除任何=
的 - 使用HMAC256与密钥签署
encoded_header.encoded_payload
,并将其编码为Base64,再次移除任何=
's - 将签名连接到前一个string,导致
encoded_header.encoded_payload.encoded_signature
在这一点上,我不知道是什么原因造成的。 我怀疑Python的HMAC或SHA256实现中的某种错误,但这似乎不太可能…任何线索?
注意:我们已经成功地复制了pyjwt
,这是python-jose
的基础。
这是因为Python字典是无序的。 如果解码两个JWT,您将看到标题部分对每个标记的sorting不同。
{ "typ": "JWT", "alg": "HS256" }
和
{ "alg": "HS256", "typ": "JWT" }
这会导致base64编码的标头不同,这将导致签名不同。
也就是说,这两者都是完全相同的索赔集合的有效标记,两者都应该validation成功。 JWT规范中没有任何规定要求等效索赔集合应该导致相等的JWT输出。
注意:我是python-jose库的作者。