【问题标题】:How to properly build json web token in python如何在python中正确构建json web token
【发布时间】:2019-03-26 17:54:16
【问题描述】:

我正在尝试使用在 python django 中构建 Json Web 令牌 pyjwt library 参考 stackoverflow 中 Madhu_Kiran_K 的建议 link

在下面的代码中,我正在尝试生成一个 JSON Web 令牌,用于存储此用户的 ID、电子邮件,并将到期日期设置为未来 2 天。 我可以成功地对令牌进行编码和解码,以获得所有必需的用户信息和令牌过期时间。

我现在的要求:

1.)请问我如何验证并确保客户端发送的令牌仍然有效,因此不会被篡改。

2.)如何检查过期时间并打印消息。 这是我为此所做的工作

#check if the token were tampered

if content['user_id'] =='' or content['email'] == '':
    print("Invalid Token")
else:
    print("Token is still valid")

#check if token has expired after 2 days

    if content['exp'] > dt:
        print("Token is still active")
    else:
        print("Token expired. Get new one")

时间到期检查返回 int 和 datetime.datetime 实例之间不支持的错误消息。什么是正确的验证方法。谢谢

以下是完整代码

#!/usr/bin/python

import sys
import re
import json

from datetime import datetime, timedelta
import jwt


#https://www.guru99.com/date-time-and-datetime-classes-in-python.html
#timedelta(days=365, hours=8, minutes=15)
#'exp': int(dt.strftime('%s'))


dt = datetime.now() + timedelta(days=2)           
encoded_token = jwt.encode({'user_id': "abc", 'email': "nancy@gmail.com", 'exp': dt }, 'MySECRET goes here', algorithm='HS256')
print(encoded_token)

#decode above token
decode_token=jwt.decode(encoded_token, 'MySECRET goes here', algorithms=['HS256'])

content = decode_token
print(content)
print(content['user_id'])
print('json token successfully retrieved')

if content['user_id'] =='' or content['email'] == '':
    print("Invalid Token")
else:
    print("Token is still valid")

#check if token has expired after 2 days

    if content['exp'] > dt:
        print("Token is still active")
    else:
        print("Token expired. Get new one")

【问题讨论】:

  • 为确保不被篡改,您可以使用安全的散列算法,例如 SHA-256。要检查时间,您不希望使用 dt,因为当您重新启动脚本时,dt 将在未来出现,理想情况下您会希望使用 dt 来构建 json 对象,但检查它应该依赖在今天的日期。只是一些想法可能会引导您朝着正确的方向前进
  • 为了检查令牌是否有效,您不应该将当前令牌与最初提供给用户的令牌进行比较吗?我想我帮不上忙,我只是觉得你的问题很有趣。
  • @MooingRawr:不确定你在说什么dt,但这似乎没有多大意义。 jwt.encode() 支持输入字典中的exp 到期日期,在再次解码时为您检查。
  • @Reez0:不需要手动检查令牌,因为它使用了数字签名。

标签: python django


【解决方案1】:

您不必手动检查令牌有效性或exp 截止日期,jwt.decode() 函数会为您验证两者

例如,如果令牌太旧,jwt.decode() 将引发 jwt.ExpiredSignatureError exception,因此只需明确地捕获它:

try:
    decode_token = jwt.decode(encoded_token, 'MySECRET goes here', algorithms=['HS256'])
    print("Token is still valid and active")
except jwt.ExpiredSignatureError:
    print("Token expired. Get new one")
except jwt.InvalidTokenError:
    print("Invalid Token")

jwt.InvalidTokenError exception 是基本异常,捕获涵盖令牌验证可能失败的所有可能方式。如果您想捕获任何子类,例如jwt.ExpiredSignatureError,请将它们放在except ...: 块中,然后再捕获InvalidTokenError

usage examples documentation,尤其是Expiration Time Claim section

过期时间在jwt.decode() 中自动验证,如果过期时间过去,则提高jwt.ExpiredSignatureError[.]

【讨论】:

  • 感谢 Martin Pieters 爵士,我很欣赏您的最佳解决方案。现在让我们考虑两种情况 1.) 我有一个要求强制每个用户获取新令牌,例如每 4 小时、8 小时或每 2 天等之后。在这种情况下,我是否必须等待 PYJWT 超时令牌作为太老了。如果 PYJWT 永恒超时怎么办。 2.)根据我在stackoverflow某处读到的内容,我的意思是,每当令牌被篡改时,用户ID或电子邮件都将为空。该方法是否不适用于 PYJWT
  • @NancyMooree:给用户一个固定的令牌,其中嵌入了时间戳。数字签名确保他们无法更改令牌,他们只能给您原始令牌而不能提供其他任何东西。在他们将该令牌返回给您的服务器之前需要多长时间都没关系,要么令牌有效(签名签出并且exp 值仍在未来),要么它不是。你不必担心,jwt.decode() 的工作就是担心验证和检查exp 的过期时间。
  • 谢谢 我现在明白了。你所有的链接都很有用。谢谢
  • @NancyMooree:我很想看看你在哪里读到了关于令牌篡改的信息。 JWT 的全部意义在于您无法篡改令牌,它已经过数字签名。已经有problems with JWT security in the past,但是如果您在解码时配置了有效、可接受的算法,那么您可以信任签名。您已经使用 algorithms=['HS256']) 做到了这一点。
猜你喜欢
  • 2015-12-14
  • 2018-01-23
  • 2016-12-20
  • 2014-05-22
  • 2015-02-12
  • 1970-01-01
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多