如何在Php中创建帐户电子邮件确认


How Do I Create a Account Email Confirmation in Php?

我正试图向用户发送一封带有链接的电子邮件(就像许多网站一样),当他们单击此链接时,他们的帐户将被激活。我在Php中究竟该如何做到这一点?

我会这样做:

1) 注册完成后,将帐户标记为非活动(等待确认),并创建两个随机字符字符串。

2) 将这两个字符串存储在数据库中,并将它们与用户关联。

3) 通过电子邮件向用户发送一个链接,该链接具有指向您网站上某个页面的链接,并且包含这两个字符串。

例如:www.mysite.com/confirm.php?auth1=j0832r2&auth2=fji4j32ion

4) 让您的页面检查两个代码是否匹配,如果匹配,请将帐户标记为活动帐户。

希望这能有所帮助。

这是我用来发送验证电子邮件的代码部分。

//create login hash
$hash = hash('whirlpool', $user->authentication->password . time() . $user->authentication->salt);
if( !Quick_Login::add($hash, $user->userid, time() + 3600, 0) )
{
    // die
}
//load email template
ob_start();
include('templates/account_create.html');
$body = ob_get_clean();
if( Mail::sendMail($user->contact->email, 'no-reply-automator@domain.com', "Email Verification", $body) )
{
    //redirect to login         
    throw new RedirectBrowserException("/index.php?code=6");
}

Mail类是我构建的一个简单的mailer,您可以很容易地使用phpmail()函数。

这里加载的电子邮件模板是这样的:

<html>
<body>
    <div style="width: 600px; border: 2px solid #E9EBF6; margin: auto; font-size: 16px; color: #555555;">
        <h1 style="margin: 0; padding: 8px; background-color: #E9EBF6; text-align: center;">
            Hello, <?=$user->fname;?>!
        </h1>
        <div style="overflow: hidden; padding: 8px; padding-top: 0; background-color: #F5F6FB;">
            <p>You are receiving this email because you (or someone pretending to be you!) has signed up for a new account on the Domain System.</p>
            <p>If you would like to verify this email account (and you must in order to use the system), please <a href="http://domain.com/components/authentication/verify.php?code=<?=$hash;?>">click this link</a>.</p>
            <p>If you don't know what this is about, or you don't want the account, simply do nothing.</p>
            <p>The quick login link above is a one-time access pass to your account.  Please use the link to verify your email address and complete your account signup.</p>
            <br />
            <p>Thanks!</p>
            <p>-Domain</p>
        </div>
    </div>
</body>
</html>

他们点击的链接指向这个脚本(verify.php):

<?php
    set_include_path('../../backbone:../../global:../../jquery:../../components:../../content:../../images:../../model:../../render:../../scripts:../../styles');
    require_once('RedirectBrowserException.php');
    require_once('User.php');
    require_once('Session.php');
    require_once('Quick_Login.php');
    setSession(0, '/');
    $code = isset($_GET['code']) ? $_GET['code'] : null;
    if( $code )
    {
        $ql = Quick_Login::getByHash($code);
        if( $ql )
        {
            $user = User::getByID($ql->userid);
            $user->disabled = 0;
            $user->save();
            setSessionVar('active', true);
            setSessionVar('roleid', $user->authentication->role->roleid);
            setSessionVar('userid', $user->userid);
            $ql->used = 1;
            $ql->save();
            throw new RedirectBrowserException("/home.php?code=0");
        }
        else
        {
            throw new RedirectBrowserException('/index.php?code=9');
        }
    }
    else
    {
        throw new RedirectBrowserException('/index.php?code=9');
    }
?>

您将在最后一个脚本中看到,它在他们的帐户上设置了disabled=0,并将他们登录(在他们的会话上设置active,并在会话上分配他们的roleiduserid)。

希望这能有所帮助。

更新

这就是在没有所有代码的情况下发生的事情

  1. 创建一个随机字符串(最好是一个不可随机猜测的字符串)
  2. 该字符串存储在数据库中,并带有指向用户ID的链接
  3. 向用户发送一封电子邮件,其中包含指向脚本和哈希的链接(例如verify.php?code=sdflnsdlknsge98y32598swob
  4. 当用户单击链接时,处理该链接的脚本会在数据库中检查该字符串(sdflnsdlknsge98y32598swob)。如果它是有效的,它会在用户的帐户上设置一个标志,表明他们已经验证了自己的电子邮件地址
  5. [可选]当用户验证其电子邮件地址时,脚本还可以自动登录

我执行以下操作。

  1. 收集他们的电子邮件地址和密码
  2. 将他们的密码存储为受保护的哈希。我使用的是PHP 7,所以我使用password_hash($user_password, PASSWORD_DEFAULT);
  3. 创建并存储一个唯一的确认ID。我是肛门和偏执狂,所以我创建了长字符串。在这种情况下,64个字符(32字节,bin2hex=64个字符)。$confirm_code = bin2hex(random_bytes(32));
  4. 通过电子邮件向用户发送使用$confirm_code构建的确认链接
  5. 当用户点击链接时,设置一个数据库标志(例如"active_user")以表示确认完成。我不会删除确认码

好吧,记住我是肛门和偏执狂。后端不会删除确认码,每个新的确认码都会根据以前的所有确认码进行检查,以确保它确实是唯一的。为什么?因此,人们不能偶然地在以后使用他们的电子邮件链接来确认一个实际上不是他们的账户,并保证没有人收到发给但可能没有被其他人使用的确认码。(记住,在计算机世界里,没有什么是"唯一的"或"随机的"。如果你不检查,你就不知道。)

此外,你永远不应该从某人的确认链接自动登录。这是一个巨大的安全违规行为。任何人都可以在激活前点击该链接,然后突然可以完全访问该帐户。始终强制用户在确认后登录。

我做过很多次的方法是在注册期间,保持成员表中"Active"的字段为bool(0或1)0为no,1为yes。在注册期间,将它们标记为0。此外,您还需要一个注册代码字段。或者你可以创建一个新的用户ID/注册代码表并进行比较

当用户注册时,创建一个唯一的代码。记录该代码并向他们发送电子邮件。当他们点击电子邮件中的链接时,检查带有代码的表,如果它与数据库中的代码匹配,则将该用户的活动字段更改为1

当他们注册时,为他们的用户名向数据库添加一个唯一的ID。还有一个"活动"列设置为0。要向他们发送电子邮件,请使用PHP mail()函数。在电子邮件中有链接到yoursite.com/activate?id=uniqueid。获取activate.php上的ID,进行一些检查,并将数据库中的"active"列设置为1。