![](/img/trans.png)
[英]What is the best way to reset (re-initialize) a list of integers (to 0) in Python
[英]what is the best way to generate a reset token in python?
我正在尝试为密码重置进行验证过程,我使用的是两个值:纪元时间,我想使用用户的旧密码 (pbkdf2) 作为密钥,
因为我不想得到非 ASCII 字符,所以我使用了SimpleEncode 库,因为它很快,因为它只是一个使用密钥的 BASE64,但问题是密码太长(196 个字符)所以我得到了一个长密钥!
我所做的是拆分结果code = simpleencode.encode(key,asci)[::30]
,但这不会是唯一的!
为了了解它是如何工作的,我尝试了 Facebook 重置过程,但给出的是一个数字! 那么这个过程是如何工作的,他们不是使用密钥来使某人难以伪造链接来重置某人的密码吗?
更新:算法将如何工作:
1- 使用 epoch time.time()
获取时间
2-生成纪元时间的Base64(用于URL)和纪元时间值+一个密钥,这个密钥是PBKDF2(密码)。
3- 生成网址 www.example.com/reset/user/Base64(time.time()) 并发送此网址 + simpleencode.encode(key,asci)[::30]
4-当用户点击URL时,他把生成的代码,这个生成的代码,如果与URL匹配,则让他修改密码,否则,它是一个忘记URL!
不确定这是最好的方法,但我可能只是生成一个 UUID4,可以在 URL 中使用它来重置密码并在“n”个时间后过期。
>>> import uuid
>>> uuid.uuid4().hex
'8c05904f0051419283d1024fc5ce1a59'
您可以使用诸如http://redis.io 之类的东西来保存该密钥,并使用相应用户 ID 的值并设置其生存时间。 因此,当某些内容来自http://example.com/password-reset/8c05904f0051419283d1024fc5ce1a59 时,它会查看它是否有效,如果有效,则允许更改以设置新密码。
如果您确实想要一个“验证引脚”,那么与令牌一起存储一个小的随机密钥,例如:
>>> from string import digits
>>> from random import choice
>>> ''.join(choice(digits) for i in xrange(4))
'2545'
并要求在重置链接上输入。
到目前为止,最简单的方法是使用ItsDangerous库:
您可以序列化用户 ID 并对其进行签名,以将时事通讯取消订阅到 URL 中。 这样您就不需要生成一次性令牌并将它们存储在数据库中。 任何类型的帐户激活链接和类似的东西都是一样的。
您还可以嵌入时间戳,因此无需涉及数据库或队列即可轻松设置时间段。 它都是经过加密签名的,因此您可以轻松查看它是否被篡改。
>>> from itsdangerous import TimestampSigner
>>> s = TimestampSigner('secret-key')
>>> string = s.sign('foo')
>>> s.unsign(string, max_age=5)
Traceback (most recent call last):
...
itsdangerous.SignatureExpired: Signature age 15 > 5 seconds
为什么不为此目的仅使用 jwt 作为令牌,也可以为其设置过期时间,因此也可以为令牌设置过期日期。
为了生成 jwt 令牌,我使用pyjwt
。 下面的代码片段显示了如何在 24 小时(1 天)的到期时间完成并使用密钥签名:
import jwt
from datetime import datetime, timedelta, timezone
secret = "jwt_secret"
payload = {"exp": datetime.now(timezone.utc) + timedelta(days=1), "id": user_id}
token = jwt.encode(payload, secret, algorithm="HS256")
reset_token = token.decode("utf-8")
下面的代码片段显示了如何在 Django 中设置令牌验证和新密码。 如果令牌已过期或已被篡改,则会引发异常。
secret = "jwt_secret"
claims = jwt.decode(token, secret, options={"require_exp": True})
# Check if the user exists
user = User.objects.get(id=claims.get("id"))
user.set_password(password)
user.save()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.