Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的电子邮件验证_Php_Mysql_Security_Registration - Fatal编程技术网

PHP中的电子邮件验证

PHP中的电子邮件验证,php,mysql,security,registration,Php,Mysql,Security,Registration,此时,用户可以在我的网站上创建一个帐户(用户名、密码、电子邮件) 这将在数据库中创建一个条目,存储用户名、密码哈希和电子邮件地址,并将用户级别设置为0。在这之后,它将发送一封包含用户id的url的电子邮件和一个新的哈希密码 $emailhash = password_hash($passwordHash, PASSWORD_BCRYPT, $options); $url = "domain/validation.php?id=$id&hash=$emailHash"; 在url指向的验

此时,用户可以在我的网站上创建一个帐户
(用户名、密码、电子邮件)

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

$emailhash = password_hash($passwordHash, PASSWORD_BCRYPT, $options);
$url = "domain/validation.php?id=$id&hash=$emailHash";
在url指向的验证页面,它将使用散列密码作为密码,并使用电子邮件中的散列来检查用户是否使用现有电子邮件地址

password_verify(hashedPasswordFromDB, hashOfHashFromEmail);
这是验证用户的安全方法,还是应该为额外的哈希添加额外的表/列?我目前的方法和/或其他方法的优缺点是什么?(例如,更简单的表格…)

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

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

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

既然我们已经进入了这一阶段,我将投入2美分,不仅要这样做,而且要把它做好

大多数人都建议在用户表中添加一列或两列。这很简单,而且很有效

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

  • 您是否也支持通过电子邮件重置密码
  • 您是否会对验证或重置进行老化
  • 你能追踪到试图泄露账户的人吗
  • 是否存在某种拒绝服务或其他问题
实现这一点的最佳方法是拥有一组与用户表相关的单独表,用于捕获这些类型的帐户事件

以下是典型帐户事件的列表:

  • 帐户注册
  • 帐户验证
  • 帐户暂停
  • 帐户删除
  • 密码重置请求
  • 更改电子邮件
在一个健壮的系统中,这些事件中的每一个都有一个时间戳,通常都有一个过期时间

它们中的许多都有一个相关的散列,需要在电子邮件中存储和发送

它们都有一个“已完成”标志,指示隐含的操作是否已完成

因此,更好的处理方法是为用户提供一个单独的相关表。为了便于讨论,该表如下所示:

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. 
这是在系统中持久化这些类型的活动所需的数据的一种更为健壮的方法,并且还有一些内置的日志记录。您有活动的审计跟踪,可以处理或防止重复请求

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


您现在有了一个系统,该系统支持其他与帐户相关的功能,而不需要单独的附加表,您可以通过创建新的事件类型来编码新事件。这些事件类型可以是字符串,但您可能还希望创建一个查找表,并将其用作用户事件表的外键。

我觉得这没问题。…这就是我如何进行“电子邮件验证”。为什么要使用密码?如果您使用的是PHP,我希望您使用。只需使用一些随机输入和电子邮件地址本身创建一个单独的sha1哈希,并将其用于哈希的输入。我在用户上有一个验证令牌列,一个随机字符串,当用户单击链接时,该字符串与用户匹配。@PraveenKumar您如何使用该设置处理电子邮件更改?@Hedylogos请参阅我的答案,了解更灵活的系统。如果您希望允许更改电子邮件地址,则可以轻松适应。当然,对于每种类型的事件,您都需要单独的处理代码。对于电子邮件更改,其工作方式通常是用户发出请求,您向他们发送电子邮件对他们请求的电子邮件进行新的验证,只有在他们验证后,你才能更改它。我添加了一个“额外”列,用于存储新电子邮件和旧电子邮件,以便在用户验证时根据请求执行操作。此外,如果需要,您可以更改令牌,并在用户验证时释放令牌,而无需更改密码。最好有一个特定的列。感谢您的明确解释,我已经记录了所有与帐户相关的内容事件中的每个事件都有一个不同的表,表中有时间戳、uid、ip和更改/发生的内容。您的表与我当前使用的表相比看起来更广泛,我非常喜欢url上有一个过期日期的可能性。我们将要求额外的var,但由于您添加了它,它已经非常完美了。