我的网站有一个循序渐进的过程来激活用户帐户的安全性。 为了获得一个帐户,用户必须填写一些表格,然后PHP在db中生成并存储它们的密钥。
然后它会向他们发送一封电子邮件,其中包含指向该过程中下一页的链接,以验证他们是否使用查询字符串密钥。
所以...
php的mail()也会发送一封类似的文本邮件:
click on the link: website.com/page.php?var=crazynumbersandletters
当这封电子邮件发送时,它会激活页面并运行php!当我检查数据库时,在点击链接之前,电子邮件中发送的页面已经处理了密钥。
据我所知,$ _GET变量对此非常糟糕,该网站即将重建,我将采用不同的方式进行激活,但为了我的理智,这是怎么发生的?
为了防止它运行,我现在要求用户通过单击按钮来触发事件。这是因为这是一封普通的短信吗? HTML电子邮件会阻止这种情况吗? (像PHPmailer类)
提前致谢!
注册页面来源:
<?php
$report = "";
//This code runs if the form has been submitted
if (isset($_POST['submit'])) {
// Connects to the Database
$dsn = "xxx";
$user = "xxx";
$password = "xxx";
$pdo = new PDO($dsn,$user,$password);
//This makes sure they did not leave any fields blank
if (!$_POST['email'] | !$_POST['pass'] | !$_POST['pass2'] | !$_POST['first_name'] | !$_POST['last_name'] ) {
die('You did not complete all of the required fields');
}
//assign name vars
$firstname = ucfirst($_POST['first_name']);
$lastname = ucfirst($_POST['last_name']);
// checks if the email is in use
$email = $_POST['email'];
$emailpieces = explode('@', $email);
if ($emailpieces[1] !== 'domain.com') {
die('Sorry, that email is invalid.');
}
$sql = "SELECT field2 FROM table WHERE field1 = :field1;";
$test = $pdo->prepare($sql);
$test->bindValue(':field1',$email);
$check = $test->rowCount();
//if the name exists it gives an error
if ($check > 0) {
die('Sorry, but '.$email.' is already in use.');
}
$pass1 = $_POST['pass'];
$pass2 = $_POST['pass2'];
// this makes sure both passwords entered match
if ($pass1 !== $pass2) {
die('Your passwords did not match.');
}
// here we encrypt the password
$pass = md5($pass1);
//create activation key
$activation_key = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);
// now we insert it into the database
$q = "INSERT INTO table (field1,field2,field3,field4,field5,field6,field7,field8,field9) ";
$q .= "VALUES (:field1,:field2,:field3,:field4,:field5,:field6,:field7,:field8,:field9);";
$stmt = $pdo->prepare($q);
$stmt->bindValue(':field1',$firstname);
$stmt->bindValue(':field2',$lastname);
$stmt->bindValue(':field3',$pass);
$stmt->bindValue(':field4','verify');
$stmt->bindValue(':field5',$email);
$stmt->bindValue(':field6',$activation_key);
$stmt->bindValue(':field7','0');
$stmt->bindValue(':field8','0');
$stmt->bindValue(':field9','0');
$stmt->execute();
$pdo = NULL;
//email user
$link = "http://www.domain.com/dir/otherpage.php?var=" . $activation_key;
$to = $email;
$subject = "Subject for email";
$message = "blah blah blah\r\n\r\n";
$message .= "Click the following link:\r\n\r\n" . $link . "\r\n\r\n";
$message .= "blah blah.\r\n\r\n\r\n";
$headers = 'From: me@domain.com\r\nReply-To: webmaster@domain.com\r\nX-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
//display results
$report = "<p><b>Thank you! An email has been sent to " . $email . " with an activation key.</b><br /><br />Please check your mail to complete registration.<br /><br />"</p>";
}
?>
验证页面来源:
<?php
//get querystring info
$activate = $_GET['var'];
//first message prompts them for action
$message = "<form action='' method='post'>";
$message .= "<p style='text-align:center;'>Click the <i>Activate</i> button to finish registration</p><br />";
$message .= "<input type='hidden' name='activate' value='" . $activate . "' />";
$message .= "<p style='text-align:center;'><input type='submit' name='submit' value='Activate' /></p>";
$message .= "</form>";
if (isset($_POST['submit'])) {
//reset message
$message = "";
//get post var
$activation_key = $_POST['activate'];
//connect to db
$dsn = "xxx";
$user = "xxx";
$password = "xxx";
$pdo = new PDO($dsn,$user,$password);
//get user info
$sql = "SELECT field1,field2,field3,field4 FROM table WHERE field5 = :field5;";
$get = $pdo->prepare($sql);
$get->bindValue(':field5',$activation_key);
$get->execute();
$result = $get->fetch(PDO::FETCH_ASSOC);
if ($get->rowCount() == 1) {
//update activation key and set password change key
$new_activation_key = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);
$password_key = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);
$q = "UPDATE table SET field1 = :field1, field2 = :field2, field3 = :field3 WHERE field4 = :field4;";
$stmt = $pdo->prepare($q);
$stmt->bindValue(':field1',$new_activation_key);
$stmt->bindValue(':field2',$password_key);
$stmt->bindValue(':field3','activated');
$stmt->bindValue(':field4',$activate);
$stmt->execute();
//set message
$message = "<p style='text-align:center;'>" . $result['firstname'] . " " . $result['lastname'] . ", your account has been activated.<br /><br />";
$message .= "Please click <a href='http://www.domain.com/dir/anotherpage.php?var=" . $password_key . "'>HERE</a> to set your password.</p>";
} else {
//failed - have user email webmaster
$subject = "Account failed activation";
$body = "Account failed to activate for <<enter your email address here>>";
//set message
$message = "<p>There was a problem activating your account.<br /><br />Please contact the <a href='mailto:me@domain.com?subject=" . $subject . "&body=" . $body . "'>WebMaster</a> to have your account activated.</p>";
}
$pdo = NULL;
}