PHP 中的电子邮件验证

Email verification in PHP

此时用户可以在我的网站上创建一个帐户(username, password, email)

这将在数据库中创建一个条目,用于存储用户名、密码哈希和电子邮件地址,并将用户级别设置为 0。之后它将发送一封带有 url,其中包含用户 ID 和哈希密码的新哈希值。

$emailhash = password_hash($passwordHash, PASSWORD_BCRYPT, $options);
$url = "domain/validation.php?id=$id&hash=$emailHash";

在 url 指向的验证页面,它将使用哈希密码作为密码,并使用电子邮件中的哈希值来检查用户是否使用现有的电子邮件地址。

password_verify(hashedPasswordFromDB, hashOfHashFromEmail);

这是一种验证用户的安全方法吗?还是我应该为额外的哈希添加额外的 table/column?还有我目前的方法and/or另一种方法的pro's/cons是什么? (例如更简单 table...)

编辑: 如果用户想要更改他的电子邮件地址(我现在正在添加的内容),我想实现相同的方法(发送一个 url 其中包含 id、新电子邮件地址和新的散列散列密码 + 新电子邮件地址)。在我看来,这看起来有点曲折,但我没有看到另一种改变它的方法。

我会说:额外的哈希值或数据库中的任何随机字符串。无需通过线路发送密码甚至散列密码。

最好创建一个单独的令牌(一些散列在 link 中作为查询发送),它与时间戳一起存储在数据库中。这样你就有了一个 link 并且可以检查时间戳,如果 link 已经过期(将令牌的时间戳与请求的当前时间进行比较(当用户打开他的 link).

既然我们已经进入这个领域,我将投入我的 2 美分,不仅要做到这一点,还要做得好。

大多数人建议您为用户添加一列或两列 table。这很简单而且有效。

但是如果你想做好这件事,你需要考虑以下事项:

  • 你们是否也支持通过电子邮件重设密码
  • 你会超时验证还是重置
  • 你能追踪到试图破坏帐户的人吗?
  • 是否存在某种拒绝服务或其他问题?

最好的方法是使用一组与用户 table 相关的单独的 table 来捕获这些类型的帐户事件。

这是典型帐户事件的列表:

  • 账号注册
  • 帐户验证
  • 帐户暂停
  • 帐户删除
  • 密码重置请求
  • 更改电子邮件

在一个健壮的系统中,这些事件中的每一个都有一个时间戳,通常都会有一个过期时间。

其中许多都有关联的哈希值,需要存储并通过电子邮件发送。

它们都有一个 "completed" 标志来指示隐含操作是否已完成。

因此,更好的处理方法是为用户提供一个单独的相关 table。为了便于讨论,这个 table 看起来像这样:

user_event
-----------
user_event_id (pk)
user_id (fk from user table)
created_on (timestamp)
event_type (registration | verification | password reset, etc)
expires_on (datetime) - manually set as is suitable
token (char40) - sha1
is_complete (tinyint)  A boolean to indicate if the action was completed
complete_on (timestamp)
user_ip (ip address of end user)
extra (varchar) : store the new email here.  Change to old email when you complete the request. 

这是一种在系统中持久保存这些类型的活动所需的数据的更强大的方法,并且还具有一些内置的日志记录。您有活动的审计线索,可以处理或防止重复请求。

您还可以使重置请求过期,并使用这些过期的请求进行老化activity,例如向从未完成注册的人发送提醒电子邮件。

您现在拥有一个支持额外帐户相关功能的系统,无需单独的额外 table,您只需创建一个新的 event_type 即可编写新事件。这些可以只是一个字符串,但您可能还想创建一个查找 table 并将其用作 user_event table.

的外键