【问题标题】:Sending an password reset email using PHP使用 PHP 发送密码重置电子邮件
【发布时间】:2012-10-06 23:31:41
【问题描述】:

如果我向用户的电子邮件地址发送一封电子邮件,其中包含指向密码重置页面的链接,我如何验证该链接?我应该在我的数据库中存储一些随机生成的密钥,然后添加到链接字符串中吗? www.mydomain.com/passwordreset.html?key=abcd1234zz235然后对照数据库中存储的密钥检查这个密钥?

如果这确实是正确的方法,我是否应该创建一些单独的表来存储这些密钥及其对应的电子邮件?如果答案是肯定的,那么我应该在用户重置密码后删除这些密钥以节省数据库空间吗?

提前谢谢你!

【问题讨论】:

  • 我在以下任何答案中都没有看到的是,您应该将访问密钥以纯文本形式存储在数据库中。它应该与用户的实际密码具有完全相同的安全性,因为它本质上是一个密码,这意味着您需要使用安全的散列函数(例如 bcrypt)对其进行散列。然后,您必须将用户 ID 连同访问密钥一起发送给用户,并将 ID 和散列访问密钥存储在数据库中。

标签: php


【解决方案1】:

这是一种非常典型的处理方式。我通常会在我的user 表中添加一个PasswordResetKey 字段。

【讨论】:

  • 如果您的电子邮件地址甚至没有在 xyz 服务中注册,您如何处理密码重置请求?
  • @Derek 你是什么意思?我不认为你的问题很清楚。
  • 如果用户决定重置地址 adfjal;sfsadfasjfkl;safj;lkjsfl;ksajf;@gmail.com 的密码,很可能该地址不存在。如果没有人拥有该地址,并且此电子邮件地址未与我的服务帐户相关联,我应该如何处理。
  • @Derek 告诉用户“重置链接已发送到您的电子邮件地址”,但如果未找到电子邮件地址/用户,则实际上不执行任何操作。
  • @Derek 从理论上讲,让用户知道电子邮件地址不存在会很好,以防他忘记了他没有使用该地址,但实际上它的信息太多了攻击者。
【解决方案2】:

我应该创建一些单独的表来存储这些密钥及其对应的电子邮件吗?

是的,我会这样做的。

如果答案是肯定的,那么我应该在用户重置密码后删除这些密钥以节省数据库空间吗?

不是因为空间,而是因为交易已经完成。

顺便说一句,你不能在这里节省空间。因为您应该在审核日志中保留密码更改事件的日志条目。

【讨论】:

  • 所以我不应该删除记录吗?我是否应该在一段时间后让每个密钥-电子邮件对超时,但保留记录?换句话说,在我的激活页面中,比如说 www.mydomain.com/resetPassword.html 我得到了当前时间,并且仅当密钥-电子邮件对的创建日期是 x 小时前时才验证重置?
  • @Derek 我只存储活动密钥,一旦使用它就将其从表中移动到您的日志中,无论您将它们存储在何处。
  • @Mahn 好的,这是有道理的。最后,通过电子邮件发送用户的电子邮件是否安全。所以domain.com/…`ksaf 这样我就可以使用reset.php 中存储在数据库中的信息来引用电子邮件来键入密钥
  • @Derek:您删除,因为交易已经完成 - 正如答案中所写。是的,您应该添加一个时间列,并在密码重置操作在一段时间后未完成时过期。例如。通过 cron 运行管理员作业,并使所有超过 48 小时的密码重置过期。告诉您的用户密码重置的有效期为 24 小时。
  • @hakre 我认为更简单的方法是存储电子邮件密钥对的创建日期,并且每当按下 activate.php 链接时,它都会检查当前时间和创建时间。如果超过 24 小时,请重定向到错误页面。
【解决方案3】:

是的,那会奏效。就我个人而言,我喜欢让密钥成为基于他们的用户数据的编码字符串,然后我可以对其进行解码。例如,我可能会获取字符串userid|password_hash|emailaddress,对其进行编码并发送。然后,当我收到它时,我可以对其进行解码并将其拆分出来。用户 ID 用于搜索数据库,然后验证 password_hash 和电子邮件,如果都验证了,那么我可以继续。

也就是说,您的解决方案可能更好,因为这意味着您知道是否实际请求了重置。归根结底,重要的是很难猜测。

【讨论】:

  • 这是一个糟糕的建议。如果您在链接中包含此类敏感信息,并且允许任何人关注它,无论是否请求重置密码,您已经为自己编写了一个严重的安全问题。您正在发送足够多的信息(未加密,请注意),以便有人接管该帐户。
  • 如果您的电子邮件地址甚至没有在 xyz 服务中注册,您如何处理密码重置请求?
  • 是的。你说“编码”。不是“加密”。我希望你知道其中的区别。
  • 使用随机令牌绝对是一个更好的主意,存储它并在使用后丢弃它。
  • @Mahn 请在上面查看我对 hakre 的评论,并提供您的意见。将不胜感激...
【解决方案4】:

看看this link,它可能会对你有所帮助。 基本上,您必须为密码重置请求创建一个表并生成一个用于识别用户和重置请求本身的密钥。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-26
    • 2016-04-04
    • 2013-12-18
    • 2015-08-13
    • 2011-04-16
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多