繁体   English   中英

如何在 Node.js 中正确实现“忘记/重置密码”功能? (使用一次性令牌)

[英]How to implement “forgot/reset password” feature properly in Node.js? (Using one time token)

我正在使用 NestJs 在 Node.js 应用程序中实现忘记/重置密码功能。

这是一般流程:

  1. 用户在“忘记密码”表单中输入他的 email 并提交请求
  2. 服务器生成一个 jwt 令牌,以用户 ID 作为有效负载,然后发送一个 email 以该令牌作为重置密码的链接(例如:GET: example.com/reset/generated_jwt_token
  3. 用户从他的 email 中点击链接,显示重置密码页面,他用新密码填写表单并以密码作为正文提交表单(例如:POST: example.com/reset/generated_jwt_token
  4. 服务器验证令牌(未过期+来自有效负载的用户 ID 存在于数据库中)并更新密码。

这种方法的主要问题是 jwt 令牌可以无限次使用来重置密码(直到它在 X 分钟后过期)。

有没有办法解决这个问题? 有人说将当前密码的 hash 作为有效载荷,因为无论如何它都会被更改并保证使用 1 次,但我不喜欢这种方法。

编辑:我遇到的另一种方法是在 jwt 令牌的数据库中创建一个不能多次使用的黑名单集合。 或者以同样的方式在 redis 中使用缓存,但似乎扩展性不是很好。

生成令牌后,您可以将其(或嵌入其中的唯一内容)保存到该用户名下的数据库中。 然后,服务器验证令牌:

(1)当点击来自reset email的链接时

(2)当用户提交重置密码页面时

通过检查令牌是否与数据库中该用户的令牌相同。

此外,当用户成功更改密码时,请从数据库中清除令牌,使其无法再次使用。

我同意@CertainPerformance 的(已接受)答案。

我想补充一下 - 考虑使用authentication-flows-js 您根本不必担心实施!

它是一个可以回答大多数流程的模块 - 身份验证、注册、忘记密码、更改密码等,并且它足够安全,因此应用程序可以使用它,而不必担心它会很容易被黑客入侵。

从我写的一篇文章中:

忘记密码

用户在忘记密码表单中输入他们的 email,然后点击提交。 服务器 (AFM) 验证帐户是否存在且未被锁定。 如果它被锁定,AFM 会抛出错误。 否则,将使用令牌向用户发送 email。 该令牌存储在数据库中用户的同一行/文档/记录中。

在此处阅读全文,了解更多说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM