这个密码重置流程有什么问题吗?
这个流程有没有什么问题呢?
- 用户在重置密码的表单中输入用户名和邮箱。
- Flask(一个Python的框架)会生成一个很长的随机字符串,并把它存储在会话中,叫做“reset_code”。会话里还会有一个“reset_pw_username”的键,用来存用户名。
- Flask会发送一封邮件,里面有一个链接,链接的格式是 /password_reset/reset_pw_username/reset_code。
- 点击这个链接后,会显示一个表单,用户可以在这里重置密码,前提是会话中的重置代码和链接中的重置代码要匹配。如果不匹配,就会出错。
- 这个重置代码在一小时后会过期。
4 个回答
1
正如Jean-Paul提到的,要求同时提供用户名和电子邮件就需要检查这两个信息是否对应同一个用户。因此,通常的做法是只要求提供用户名或电子邮件中的一个,确认它们在你的数据库中存在,然后将恢复链接发送到相应的地址。
把恢复令牌存储在会话数据中可能会让一些用户觉得麻烦,正如phihag所说。通常,这些令牌会存放在普通的数据库里。不过,需要注意的是,这些令牌是等同于密码的:一旦获得,就可以用它们来获取密码。因此,在存储到数据库之前,必须对它们进行加盐和哈希处理(和处理密码的方式一样安全)。这也意味着,你的恢复处理程序在查找数据库中的令牌之前,必须先对接收到的令牌进行加盐和哈希处理。
4
如果我可以输入一个用户名和电子邮件地址,那么我就可以让系统把任何用户的重置密码的链接发到我的邮箱里。也许你们应该确认一下,这个电子邮件地址确实是要重置密码的用户自己拥有的。
2
你需要确保输入的用户名和邮箱与某个账户匹配(或者一开始就用邮箱作为用户名)。
从用户体验的角度来看,如果打开邮件中链接的浏览器和最开始使用的浏览器不一样,这个方法就行不通了。
除此之外,你还要特别注意重置代码的随机性(长度倒不是特别重要)。这个代码应该是加密随机的(也就是说要用 os.urandom
),这样攻击者就无法轻易猜到。像 random.random
这样的随机方法就不适合。