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

Posted

技术标签:

【中文标题】如何在 Node.js 中正确实现“忘记/重置密码”功能? (使用一次性令牌)【英文标题】:How to implement "forgot/reset password" feature properly in Node.js? (Using one time token) 【发布时间】:2021-03-26 12:11:22 【问题描述】:

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

这是一般流程:

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

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

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

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

【问题讨论】:

【参考方案1】:

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

(1) 点击重置邮件中的链接时

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

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

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

【讨论】:

【参考方案2】:

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

我想添加 - 考虑使用 authentication-flows-js。 您完全不必担心实施!

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

来自我写的一篇文章:

忘记密码

用户在忘记密码时输入了他们的电子邮件 表格,然后点击提交。服务器 (AFM) 验证帐户是否存在 并且没有被锁定。如果它被锁定,AFM 会抛出错误。否则,一个 电子邮件通过令牌发送给用户。该令牌存储在数据库中 在用户的同一行/文档/记录中。

Read the full article with more explanations here.

【讨论】:

以上是关于如何在 Node.js 中正确实现“忘记/重置密码”功能? (使用一次性令牌)的主要内容,如果未能解决你的问题,请参考以下文章

如何在python的类中正确实现辅助函数

在这种情况下,如何在 Flutter 中正确实现 FutureBuilder?

如何在php中正确实现结构化菜单

ios - 如何在 ios swift 中正确实现后台获取

如何在 Keras 中正确实现自定义活动正则化器?

如何在 Windows 10 UWP 中正确实现语音识别