PDO邮箱验证
PDO email verification
我正在尝试制作用户注册脚本。
在我的 registration.php
脚本中,我验证用户输入然后将它们插入数据库。然后我想使用 SMTP 在电子邮件中向用户发送验证 link:
$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;
}
到目前为止,所有这些工作正常,注册用户收到一封随机创建的 link 的电子邮件。
这里是 link 用户获得的示例:http://url/to/verification.php?verification_code=80371b8ff9b0d5fb444f4be68c8b5a0d9757603b
当他们点击 link 时,他们会被定向到我的 verification.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!";
}
}
}
好吧,这是我头疼的问题,我希望我能正确解释一下:
所有这些都有效。当我创建第一个用户时,它会在注册后运行,我可以在数据库中看到验证码,当我单击 link 时,它会被激活。但是当我点击 registration.php 脚本时,以下正在注册的用户会立即被激活!这就像两个脚本都同时 运行 然后完全不需要激活 link。
我不知道是什么导致了这种行为。是因为我的第一个脚本没有正确关闭我的 pdo 连接吗?是因为 PHP 通常只是 运行 一个目录中的所有脚本,而我只调用一个吗?是因为我不明白 $_GET 函数是如何工作的吗?
我无法找到为什么这不起作用的方法,所以这是我已经尝试过的一些方法:
- 我尝试注册一个用户,verification.php 脚本被注释掉,然后先取消注释,然后在用户注册时单击正在发送的 link。这有效。
- 我试过将 verification.php 脚本移动到另一个文件夹。没有任何帮助
- 我尝试关闭 verification.php 中的连接,然后创建一个新的 PDO。这也不起作用。
- 我尝试了很多方法来更改 $_GET 方法,但都没有成功。
更新!:现在我试图查看代码中断的确切位置,我发现了一些不寻常的地方。当 registration.php 为 运行 时,用户在数据库中被设置为不活动。我一收到带有 link 的电子邮件。用户设置为活动状态,无需单击 link
请告诉我有人知道发生了什么事。
问题是第一个用户注册时 table 完全是空的
但是当第二个用户注册并输入没有获取值的 verification.php 时,它会搜索具有 verification = 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!";
}
}
}
我正在尝试制作用户注册脚本。
在我的 registration.php
脚本中,我验证用户输入然后将它们插入数据库。然后我想使用 SMTP 在电子邮件中向用户发送验证 link:
$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;
}
到目前为止,所有这些工作正常,注册用户收到一封随机创建的 link 的电子邮件。
这里是 link 用户获得的示例:http://url/to/verification.php?verification_code=80371b8ff9b0d5fb444f4be68c8b5a0d9757603b
当他们点击 link 时,他们会被定向到我的 verification.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!";
}
}
}
好吧,这是我头疼的问题,我希望我能正确解释一下:
所有这些都有效。当我创建第一个用户时,它会在注册后运行,我可以在数据库中看到验证码,当我单击 link 时,它会被激活。但是当我点击 registration.php 脚本时,以下正在注册的用户会立即被激活!这就像两个脚本都同时 运行 然后完全不需要激活 link。
我不知道是什么导致了这种行为。是因为我的第一个脚本没有正确关闭我的 pdo 连接吗?是因为 PHP 通常只是 运行 一个目录中的所有脚本,而我只调用一个吗?是因为我不明白 $_GET 函数是如何工作的吗?
我无法找到为什么这不起作用的方法,所以这是我已经尝试过的一些方法:
- 我尝试注册一个用户,verification.php 脚本被注释掉,然后先取消注释,然后在用户注册时单击正在发送的 link。这有效。
- 我试过将 verification.php 脚本移动到另一个文件夹。没有任何帮助
- 我尝试关闭 verification.php 中的连接,然后创建一个新的 PDO。这也不起作用。
- 我尝试了很多方法来更改 $_GET 方法,但都没有成功。
更新!:现在我试图查看代码中断的确切位置,我发现了一些不寻常的地方。当 registration.php 为 运行 时,用户在数据库中被设置为不活动。我一收到带有 link 的电子邮件。用户设置为活动状态,无需单击 link
请告诉我有人知道发生了什么事。
问题是第一个用户注册时 table 完全是空的 但是当第二个用户注册并输入没有获取值的 verification.php 时,它会搜索具有 verification = 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!";
}
}
}