首先,我们需要知道您已经了解的关于用户的信息。显然,您有一个用户名和旧密码。您还知道什么?您是否拥有电子邮件地址?您是否拥有有关用户最喜欢的花卉的数据?
假设您有用户名、密码和有效的电子邮件地址,您需要向用户表(假设它是数据库表)添加两个字段:一个名为new_passwd_expire的日期和一个名为new_passwd_id的字符串。
假设您知道用户的电子邮件地址,当有人请求重置密码时,您需要按照以下方式更新用户表:
new_passwd_expire = now() + some number of days
new_passwd_id = some random string of characters (see below)
接下来,您需要向该地址的用户发送电子邮件:
亲爱的某某,
有人请求重置<username>在<your website name>的用户帐户密码。如果您确实请求此密码重置,请单击以下链接:
http://example.com/yourscript.lang?update=<new_password_id
如果该链接不起作用,您可以转到http://example.com/yourscript.lang,并在表格中输入以下内容:<new_password_id>
如果您没有请求密码重置,则可以忽略此电子邮件。
谢谢,yada yada
现在,编写yourscript.lang:此脚本需要一个表格。如果URL上传递了var update,则该表单仅要求用户的用户名和电子邮件地址。如果未传递更新,则它会要求用户名、电子邮件地址和发送到电子邮件中的id代码。您还要求输入新密码(当然要输入两次)。
为了验证用户的新密码,您需要验证用户名、电子邮件地址和id代码是否匹配,请求是否过期以及两个新密码是否匹配。如果成功,您将更改用户的密码为新密码并从用户表中清除密码重置字段。还要确保注销用户/清除任何与登录相关的cookie并将用户重定向到登录页面。
基本上,new_passwd_id字段是仅在密码重置页面上有效的密码。
一个潜在的改进:您可以从电子邮件中删除<username>。"有人请求重置此电子邮件地址上的帐户密码..."这样,如果电子邮件被拦截,用户名就是用户所知道的内容。我一开始没有这样做,因为如果有人攻击该帐户,他们已经知道用户名了。这种增加的模糊性可以在某些情况下防止机会攻击。
至于您的问题:
生成随机字符串:它不需要非常随机。任何GUID生成器或甚至是md5(concat(salt,current_timestamp()))都足够了,其中salt是用户记录上的某些东西,例如账户创建时的时间戳。它必须是用户看不到的内容。
计时器:是的,您需要这样做只是为了保持数据库的正常状态。最多只需要一周,但至少要2天,因为您永远不知道电子邮件延迟可能持续多长时间。
IP地址:由于电子邮件可能会延迟数天,因此IP地址仅用于日志记录,而不用于验证。如果要记录它,请这样做,否则您不需要它。
重置屏幕:请参见上文。