javascript - 如何在 Node.js 中正确实现“忘记/重置密码”功能?(使用一次性令牌)
问题描述
我正在使用 NestJs 在 Node.js 应用程序中实现忘记/重置密码功能。
这是一般流程:
- 用户以“忘记密码”的形式输入他的电子邮件并提交请求
- 服务器生成一个以用户 ID 作为有效负载的 jwt 令牌,然后以该令牌作为链接发送一封电子邮件以重置密码(例如:GET:
example.com/reset/generated_jwt_token
) - 用户从他的电子邮件中点击链接,显示重置密码页面,他用新密码填写表单并以密码作为正文提交表单(例如:POST
example.com/reset/generated_jwt_token
:) - 服务器验证令牌(未过期+来自有效负载的用户 ID 存在于数据库中)并更新密码。
这种方法的主要问题是 jwt 令牌可以无限次使用来重置密码(直到它在 X 分钟后过期)。
有没有办法解决这个问题?有人说将当前密码的哈希值作为有效负载,因为无论如何它都会被更改并保证 1 次使用,但我不喜欢这种方法。
编辑:我遇到的另一种方法是在 jwt 令牌的数据库中创建一个不能多次使用的黑名单集合。或者以同样的方式在redis中使用缓存,但是看起来扩展性不是很好。
解决方案
生成令牌后,您可以将其(或嵌入其中的唯一内容)保存到该用户名下的数据库中。然后,服务器验证令牌:
(1) 当点击来自重置邮件的链接时
(2)当用户提交重置密码页面时
通过检查令牌是否与数据库中该用户的令牌相同。
此外,当用户成功更改密码时,请从数据库中清除令牌,使其无法再次使用。
推荐阅读
- android - Jenkins Mac Xamarin UI 测试失败
- ubuntu - KVM - 无法连接到管理程序错误
- c++ - 使用 MPI 在超立方体中广播
- c# - 从 DBPedia 服务获取信息
- vue.js - vue.js test-utils 为什么我的 onSubmit 函数 mock 没有被调用?
- python - 大型数据集上的 predict_on_batch() 内存错误
- javascript - Yargs 帮助不显示所有帮助选项
- xamarin - 如何在本机 Xamarin.Mac 中嵌入 Xamarin.Forms?
- ios - iOS 使用嵌套请求加载表数据
- javascript - React 中显示接收数据的问题