好的,我有此代码可以发送电子邮件帐户验证链接
$verifyemail = $clean['email'];
$to = $verifyemail;
$subject = 'Virtual Pierz Close | Verify Your Account';
$message = "Thanks for registering with VPC, on clicking the verification link below, your account will be confirmed, you can then go ahead buy Virtual Properties, donating £5 each time to the worthwhile charity.
http://www.cambrianvacation.co.uk/vpc/registered.php?
email='$verifyemail'&hash='$hash1' ";
$headers = 'From:noreply@cambrianvacation.co.uk'; // Set from headers
mail($to, $subject, $message, $headers);
然后我有了这个代码,试图通过在数据库中设置active = 1来激活帐户,然后在登录时将其作为访问控制逻辑的一部分,没有active = 1,没有登录,其中其他保护
if(isset($_GET['email']) && !empty($_GET['email']) AND isset($_GET['hash']) && !empty($_GET['hash'])){
// Verify data
$accountemail = $_GET['email'];
$accounthash = $_GET['hash'];
}
$accountActive = 1;
$notactive = 0;
$username = '';
$password2 = '';
$username = 'xxxxxxx';
$password2 = 'xxxxxxx';
$db1 = new PDO('mysql:host=localhost;dbname=xxxxxxxxxxxxx', $username, $password2, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$db1->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try{
$search = $db1->prepare("SELECT email, hash, active FROM users WHERE email = :email AND hash= :hash AND active = :active");
$search->bindParam(':email', $accountemail);
$search->bindParam(':hash', $accounthash);
$search->bindParam(':active', $notactive);
$search->execute();
$colcount = $search->columnCount();
}catch(PDOException $e) {
$e->getMessage();
}
print_r($colcount);
if($colcount === 3){
//try{
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash AND active = :active");
$update->bindParam(':active', $accountActive);
$update->bindParam(':email', $accountemail);
$update->bindParam(':hash', $accounthash);
$update->bindParam(':active', $notactive);
$update->execute();
//}catch(PDOException $e) {
// $e->getMessage();
//}
但是我无法让活动列更新。
我还考虑过使用GET ['email']可能受到语义网址攻击,但是如果没有匹配的哈希值,逻辑将不会激活帐户,哈希是随机生成的,使用crypt()... ...... 如果有人能在代码中看到任何安全漏洞,请告诉我.........
答案 0 :(得分:0)
您的新参数未正确绑定,请更改:
$update = $db1->prepare("UPDATE users SET active=? WHERE email=? AND hash=? AND active = ?");
要:
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
编辑 - 完整更新代码:
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");
$update->bindParam(':active', $accountActive);
$update->bindParam(':email', $accountemail);
$update->bindParam(':hash', $accounthash);
$update->execute();
答案 1 :(得分:0)
你能做什么,根本不包括“电子邮件”。
您可以尝试通过这样做来生成网址:
$secret = "1032940fdjsjdkf#@$!@#%djsfisd";
$hash = md5($email.$secret);
$url = "http://www.cambrianvacation.co.uk/vpc/registered.php?hash=".$hash;
答案 2 :(得分:0)
这里没有理由进行两次单独的查询。为什么不只是有一个查询来更新基于哈希和电子邮件和active = 0的记录?如果修改行的计数= 1,那么您就成功了,否则您就失败了。您可能不关心它为什么会失败,因为从安全角度来看,向用户回复更新失败的原因(即错误的电子邮件,错误的哈希,已经活跃的用户等)会很糟糕。
话虽如此,您的问题实际上在于您的更新使用?
样式绑定,而您正在使用带有bindParam()
样式绑定的:param
。这不起作用,因为准备好的声明中没有这些值。
所以只需使用这一个查询:
UPDATE users SET active = 1 WHERE email = :email AND hash = :hash AND active = 0
显然,如果您认为您要更改活动/非活动的值,那么也可以随意使用参数,但我想您可能希望将其视为布尔样式的tinyint字段只允许0和1的值,所以在那里进行参数化确实没有意义。
答案 3 :(得分:0)
在更新查询中,您使用的是“?”对于参数,但是您尝试使用bindParam()将它们设置为named。你应该使用
$update->execute(array($accountActive, $accountemail, $accounthash, $notactive));
或者以这种方式修改更新查询:
$update = $db1->prepare("UPDATE users SET active=:active WHERE email=:email AND hash=:hash");