【问题标题】:PDO email verificationPDO 电子邮件验证
【发布时间】:2015-04-21 06:13:27
【问题描述】:

我正在尝试制作用户注册脚本。

在我的registration.php 脚本中,我验证用户输入,然后将它们插入数据库。然后,我想使用 SMTP 在电子邮件中向用户发送验证链接:

$user_activation_hash = sha1(uniqid(mt_rand(), true)); //creating ramdom string

    $mail = new PHPMailer;
    $mail->IsSMTP();
    $mail->CharSet = 'UTF-8';

    $mail->Host       = "info";         // SMTP server
    $mail->Username   = "info"; // SMTP account username
    $mail->Password   = "info";                 // SMTP account password
    $mail->SMTPAuth   = true;                       // enable SMTP authentication
    $mail->Port       = info;                       // set the SMTP port for the server

    $mail->From       = "info"; //the email the mail comes from
    $mail->FromName   = "someName";                 //what name should be shown at the email
    $mail->AddAddress($email);                      //where the mail should be sent to
    $mail->Subject    = "email validation";         //subject of the mail

    //how the link should look in the mail the "url" should point to the verification.php file
    $link = "url path to my verification.php script".'?verification_code='.urlencode($user_activation_hash);

    //the message in the mail with the above link
    $mail->Body = "Please click on this link to activate your account:".' '.$link;

    if(!$mail->Send()) {
        echo "there was an error sending the mail" . ' ' . $mail->ErrorInfo;

        //if there is an error sending the mail then I delete it here

        return false;

    } else {
        //here I update the user with the new random created string

        $sql = 'UPDATE `user` SET verification = :verification WHERE Id = :Id';
        $stmt = $dbh->prepare($sql);
        $stmt->bindParam(':Id', $Id, PDO::PARAM_STR);
        $stmt->bindParam(':verification', $user_activation_hash, PDO::PARAM_STR);
        $stmt->execute();

        $dbh = null;

        return true;
    }

到目前为止,所有这些都可以正常工作,注册用户会收到一封包含创建随机链接的电子邮件。

这是用户获取的链接示​​例:http://url/to/verification.php?verification_code=80371b8ff9b0d5fb444f4be68c8b5a0d9757603b

当他们点击链接时,他们会被定向到我的 verify.php 脚本:

if(!empty($_GET['verification_code']) && isset($_GET['verification_code'])){
$verificationCode = $_GET['verification_code'];

//check the database for the verification code from the link
$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification AND isActive = 0';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':verification', $verificationCode, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch();

$Id = $row['Id'];

if (empty($row)){
        echo "the account was not found";
    }else{
        //if they match. make the user active in db
        $sql = 'UPDATE user SET isActive = 1, verification = NULL WHERE Id=:Id';
        $stmt = $dbh->prepare($sql);
        $stmt->bindParam(':Id', $Id, PDO::PARAM_STR);
        $stmt->execute();
        $row = $stmt->fetch();

        echo "The account has been activated!";
    }

}
}

好的,这是我的头痛,我希望我能正确解释:

所有这些都有效。当我创建第一个用户时,它在注册后工作,我可以在数据库中看到一个验证码,当我点击链接时它被激活。但是当我点击registration.php脚本时,以下注册用户会立即被激活!这就像两个脚本同时运行,然后完全不需要激活链接。

我不知道是什么导致了这种行为。是因为我的第一个脚本没有正确关闭我的 pdo 连接吗?是因为 PHP 通常只在我调用一个目录时运行目录中的所有脚本吗?是不是因为我不明白 $_GET 函数是如何工作的?

我无法找到为什么这不起作用的方法,所以这里是我已经尝试过的一些事情:

  • 我尝试注册用户时将verification.php 脚本注释掉,然后先取消注释并单击用户注册时发送的链接。这行得通。
  • 我尝试将我的 verify.php 脚本移动到另一个文件夹。没有任何帮助
  • 我尝试在verification.php 中关闭连接,然后创建了一个新的PDO。这也不起作用。
  • 我尝试了很多方法来更改 $_GET 方法,但都没有成功。

更新!:现在我试图查看代码中断的确切位置,我注意到一些不寻常的地方。运行registration.php 时,用户在数据库中设置为不活动。一旦我收到带有链接的电子邮件。用户被设置为活动,无需点击链接

请告诉我外面有人知道发生了什么。

【问题讨论】:

  • 第一个用户被激活后。它的验证值为空。下一个到达验证页面的用户,其验证码未设置(即为空)。执行以下查询:select from users where verification = null。这将返回第一个用户。
  • 是的,但在第二个用户之前,他使用了verification.php,他已经注册了一个帐户,因此从电子邮件中获得了一个他使用的新验证码?
  • 你没有在第一个脚本中告诉我们$Id应该来自哪里。
  • 很抱歉我没有包含它,因为我知道该部分工作正常,用户总是被注册。它来自 html 表单中的 $_POST 函数
  • 哦,对不起,这不正确,这是所有用户信息。 Id 源自我的 mysql 数据库,我使用 sql SELECT * FROM user WHERE email=:email 因为电子邮件始终是唯一的

标签: php mysql email pdo


【解决方案1】:

问题是第一个用户注册的时候表是空的 但是当第二个用户注册并输入没有获取值的verification.php时,它会搜索具有验证= null的用户(第一个用户) 并轻松完成代码,因此您只需要修改代码即可

只需编辑verification.php文件中的第一个查询而不是这个

$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification';

这样做

$sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification AND isActive = 0';

用于检查是否发送了值

if(isset($_GET["verification_code"]){
    $sql = 'SELECT Id, verification FROM `user` WHERE verification = :verification AND isActive = 0';
    $stmt = $dbh->prepare($sql);
    $stmt->bindParam(':verification', $verificationCode, PDO::PARAM_STR);
    $stmt->execute();
    $row = $stmt->fetch();

    $Id = $row['Id'];

    if ($Id == null){
        echo "the account was not found";

    }else{

// check if the verificationcode found in the database, matches the verificationcode from the link
if ($row['verification'] !== $verificationCode) {

    //checking if it already exists and if there is an error then deleting the user

} else {

    //if they match. make the user active in db
    $sql = 'UPDATE user SET isActive = 1, verification = NULL WHERE Id=:Id';
    $stmt = $dbh->prepare($sql);
    $stmt->bindParam(':Id', $Id, PDO::PARAM_STR);
    $stmt->execute();
    $row = $stmt->fetch();

    echo "The account has been activated!";

}
}
}

【讨论】:

  • 这不起作用。但是verification.php 从链接中获取它的GET 值?我对么?我将通过发送给注册用户的链接示例来更新问题
  • 首先唯一的方法是从 URL 中获取值这不是你的问题解决的问题是你将 isActive 值更改为在数据库中输入它的默认值,然后您可能要做的另一件事是检查是否发送了获取值我正在为此编辑我的答案
  • 这似乎有效!我不太明白为什么......因为现在我的 $verificationCode 是空的?它怎么可能仍然找到用户并运行更新?当 $verificationCode 为空时,我无法使用 select 方法找到用户?我可以吗?
  • 直到通过 Get 方法在 url 中发送的验证码参数才会运行选择和更新语句,除非如果用户尝试在未发送验证码的情况下进入页面,您可以在回显消息中添加一些其他内容您可以在 select 语句之后检查行数
  • 完全激活的用户验证为null,get等于null,因此代码在添加if语句之前很容易运行
猜你喜欢
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 2013-11-05
  • 2023-04-06
  • 2011-09-25
  • 2017-03-03
相关资源
最近更新 更多