4

我的用例是为重置密码 API 生成令牌。我正在用 python 中的危险库来做这件事。 https://pythonhosted.org/itsdangerous/

此令牌(在重置密码链接内)是通过电子邮件转发给客户端的,令牌有过期时间限制,经过验证,密码重置可以成功通过。

这里的问题是,一旦密码重置成功,我如何确保在到期时限内不能再次使用相同的令牌(电子邮件链接)。我可以看到 itsdangerous 有 URLSafeTimedSerializer,它有助于在验证阶段评估令牌的年龄。另一方面,TimedJSONWebSignatureSerializer 有助于在生成令牌时设置到期时间。请检查随附的代码。

有没有更好的方法强制使令牌过期?如果不是,那么保存已使用令牌状态的最佳方法是什么?

import itsdangerous

key = "test"

# signer = itsdangerous.URLSafeTimedSerializer(key)
signer = itsdangerous.TimedJSONWebSignatureSerializer(key, expires_in=5)
email = "email@test.com"

# token = email  # to be used with URLSafeTimedSerializer
token = signer.dumps({"email": email})

print token

# print signer.loads(token, max_age=5) # to be used with URLSafeTimedSerializer
print str(signer.loads(token)["email"]) # to be used with TimedJSONWebSignatureSerializer
4

2 回答 2

1

一旦您的令牌生成并签名,它就会一直有效,直到它过期。你不能再改变它了。考虑到这一点,这也意味着一旦签名就不能更改其任何有效负载,否则它将被视为无效(由于签名无效)。

但是,您可以做的一件事是在生成"some_key"令牌并将密钥存储在数据库中后生成唯一密钥 ( )。最后,将发布给用户的令牌有效负载可能如下所示{"email": email, "reset_key": "some_key"}

每次有人尝试重置他的密码时,您只需先验证该密钥即可允许或拒绝请求。

重置成功后,您只需从数据库中删除该密钥(或将其标记为无效)。这将使包含相同令牌的以下请求无效,即使令牌本身从到期角度来看仍然有效。

我希望这会有所帮助!

于 2019-05-16T13:59:18.357 回答
0

我意识到这是一个迟到的答案,所以为了其他人发现这个问题而添加。

另一种方法可能是使用布尔会话变量,例如,一旦令牌被反序列化,就将其tokenused设置为;True从而使令牌的使用无效。

例如,使用sessionFlask 中的对象:

    uid = {}
    try:
        if not session['tokenused']:
            session['tokenused'] = True
            s = Serializer(app.config['SECRET_KEY'])
            uid = s.loads(token)
    except Exception as err:
        errors.internal_server_error(err)
    return uid
于 2020-08-02T21:18:00.563 回答