PHP MSQLI忘记密码重置页面

时间:2017-02-21 15:44:01

标签: php html mysql

我正在为我的网站(www.qbstaxsubmission.co.uk)设置一个PHP丢失的密码页面,并且创建丢失的密码电子邮件的代码发送给用户工作正常。但是,当用户点击电子邮件链接时,他会到达新的密码php页面。这是该页面上的脚本,它会生成一条错误消息“更新恢复密钥时注册失败:INSERT”,它会激活我的样式化错误页面,将用户转移回我的标准登录页面。

所以我的问题是我无法看到我的新密码.php出了什么问题。任何人都可以帮忙吗?

这是全新的password2.php代码:

<?php
ob_start();
include ('config.php');
include ('function.php');
$error_msg = "";

$token = $_GET['token'];
$userID = UserID($email);
$verifytoken = verifytoken($userID, $token);

// Sanitize and validate the data passed in
if (isset($_POST['submit'],$_POST['username'], $_POST['email'],       $_POST['p'])) {   
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING);
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);   
$new_password = filter_input(INPUT_POST, 'new_password', FILTER_SANITIZE_STRING);
$retype_password = filter_input(INPUT_POST, 'retype_password', FILTER_SANITIZE_STRING);
$id = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_STRING);}

$new_password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($new_password) != 128) {
// The hashed pwd should be 128 characters long.
// If it's not, something really odd has happened
$error_msg .= '<p class="error">Invalid password configuration.</p>';
}

$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt = $db ->prepare($prep_stmt);    
if ($stmt) {
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->store_result();

if ($stmt->num_rows == 1) {
// A user with this email address already exists
$error_msg .= '<p class="error">A user with this email address already exists.</p>';
}
} else {
$error_msg .= '<p class="error">Database error</p>';
}

if($new_password != $retype_password) {
// Create a random salt
$salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
// Create salted password 
$new_password = hash('sha512', $random_salt . $salt);

}

// Insert the new hashed password into the database
if ($insert_stmt = $db->prepare("UPDATE members SET password = ? WHERE id = ? ")) {
$insert_stmt->bind_param('si', $newpassword, $id);
// Execute the prepared query.
if (!$insert_stmt->execute()) {
header('Location: ../error.php?err=Database Registration failure: INSERT');
}

// Update recovery key      
if ($insert_stmt = $db->prepare("UPDATE recovery_keys SET valid = 0 WHERE  id = ?  AND token = ? ")); 
$insert_stmt->bind_param('is', $id, $token);
// Execute the prepared query.
if ($insert_stmt->execute())  
$msg = 'Your password has changed successfully. Please login with your new password.';

}else
{


header('Location: ../error.php?err=Registration failure in updating recovery key: INSERT'); }

{exit();}


?>

当上面的代码运行时,我得到一个空白页面,其中包含站点链接中显示的正确令牌代码。

此password2.php页面包含一个功能页面,如下所示。

function checkUser($email)
{
global $db;

$query = mysqli_query($db, "SELECT id FROM members WHERE email = '$email'");

if(mysqli_num_rows($query) > 0)
{
return 'true';
}else
{
return 'false';    }
}

function id($email)
{
global $db;

$query = mysqli_query($db, "SELECT id FROM members WHERE email = '$email'");
$row = mysqli_fetch_assoc($query);

return $row['id'];
}


function generateRandomString($length = 25) {
// This function has taken from stackoverflow.com

$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return md5($randomString);
}

function send_mail($to, $token)
{
require 'PHPMailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
//$mail->SMTPDebug = 3;     

$mail->isSMTP();  
$mail->Host = '';
$mail->SMTPAuth = true;
$mail->Username = '';
$mail->Password = '';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465; 
$mail->SetFrom = '';
$mail->FromName = '';
$mail->addAddress($to);
$mail->addReplyTo('', 'Reply');
$mail->isHTML(true);    
$mail->Subject = 'Company Password Recovery Instruction';
$link = 'x.php?email='.$to.'&token='.$token;
$mail->Body  = "<b>Hi</b><br><br>You have just requested a new password for your company account with QBS Tax Submission. <a href='$link' target='_blank'>Click here</a> to reset your password. If you are unable to click the link then copy the hyper link below and paste into your browser to reset your password.<br><i>". $link."</i>";

$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if(!$mail->send()) {
return 'fail';
} else {
return 'success';
}
}

function verifytoken($id, $token)
{   
global $db;
$query = mysqli_query($db, "SELECT valid FROM recovery_keys WHERE id = $id AND token = '$token'");
$row = mysqli_fetch_assoc($query);  
if(mysqli_num_rows($query) > 0)
{
if($row['valid'] == 1)
{
return 1;
}else
{
return 0;
}
}else
{
return 0;
}

}

function login($email, $password, $mysqli) {
// Using prepared statements means that SQL injection is not possible. 
if ($stmt = $mysqli->prepare("SELECT id, username, email, password, salt
              FROM members 
                              WHERE email = ? LIMIT 1")) {
$stmt->bind_param('s', $email);  // Bind "$email" to parameter.
$stmt->execute();    // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($id, $username, $db_password, $salt);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// If the user exists we check if the account is locked
// from too many login attempts 
if (checkbrute($id, $mysqli) == true) {
// Account is locked 
// Send an email to user saying their account is locked 
return false;
} else {
// Check if the password in the database matches 
// the password the user submitted.
if ($db_password == $password) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$id = preg_replace("/[^0-9]+/", "", $id);
$_SESSION['id'] = $id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $password . $user_browser);
// Login successful. 
return true;
} else {
// Password is not correct 
// We record this attempt in the database 
$now = time();
if (!$mysqli->query("INSERT INTO login_attempts(id, time) 
VALUES ('$id', '$now')")) {
header("Location: ../error.php?err=Database error: login_attempts");
exit();
}
return false;
}
}
} else {
// No user exists. 
return false;
}
} else {
// Could not create a prepared statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
}
function checkbrute($id, $mysqli) {
// Get timestamp of current time 
$now = time();
// All login attempts are counted from the past 2 hours. 
$valid_attempts = $now - (2 * 60 * 60);
if ($stmt = $mysqli->prepare("SELECT time 
                              FROM login_attempts 
                              WHERE id = ? AND time > '$valid_attempts'")) {
$stmt->bind_param('i', $id);
// Execute the prepared query. 
$stmt->execute();
$stmt->store_result();
// If there have been more than 5 failed logins 
if ($stmt->num_rows > 5) {
return true;
} else {
return false;
}
} else {
// Could not create a prepared statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
}
function login_check($mysqli) {
// Check if all session variables are set 
if (isset($_SESSION['id'], $_SESSION['username'],      $_SESSION['login_string'])) {
$id = $_SESSION['id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
if ($stmt = $mysqli->prepare("SELECT password 
                  FROM members 
                  WHERE id = ? LIMIT 1")) {
// Bind "$id" to parameter. 
$stmt->bind_param('i', $id);
$stmt->execute();   // Execute the prepared query.
$stmt->store_result();
if ($stmt->num_rows == 1) {
// If the user exists get variables from result.
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password . $user_browser);
if ($login_check == $login_string) {
// Logged In! 
return true;
} else {
// Not logged in 
return false;
}
} else {
// Not logged in 
return false;
}
} else {
// Could not prepare statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
} else {
// Not logged in 
return false;
}
}
function esc_url($url) {
if ('' == $url) {
    return $url;
}
$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);

$strip = array('%0d', '%0a', '%0D', '%0A');
$url = (string) $url;

$count = 1;
while ($count) {
    $url = str_replace($strip, '', $url, $count);
}

$url = str_replace(';//', '://', $url);
$url = htmlentities($url);

$url = str_replace('&amp;', '&#038;', $url);
$url = str_replace("'", '&#039;', $url);
if ($url[0] !== '/') {
    // We're only interested in relative links from $_SERVER['PHP_SELF']
    return '';
} else {
    return $url;
}
}

1 个答案:

答案 0 :(得分:1)

我相信这就是问题所在:

    if (! $insert_stmt->execute())  
    $msg = 'Your password has changed successfully. Please login with your new password.';

}else{..}

if (! $insert_stmt->execute())这意味着如果查询失败,则表示密码失败.....

您的代码始终显示更新恢复密钥时注册失败的原因:INSERT ,因为您指示您的代码在查询未失败时必须生成该代码。

你的代码全部乱了,你需要清理它。

这应该是这样的。

 if ($insert_stmt = $db->prepare("UPDATE recovery_keys SET valid = 0 WHERE userID =  ?  AND token = ? ")); 
    $insert_stmt->bind_param('ss', $userID, $token);
    // Execute the prepared query.
    if ($insert_stmt->execute())  
    $msg = 'Your password has changed successfully. Please login with your new password.';

    }else
    {
    $msg = "Password doesn't match";

    header('Location: ../error.php?err=Registration failure in updating recovery key: INSERT'); }

    {exit();}

修改

试图清理代码中的一些混乱。现在应该怎么看。

<?php
ob_start();
include('config.php');
include('function.php');
$error_msg = "";

$token       = $_GET['token'];
$userID      = UserID($email);
$verifytoken = verifytoken($userID, $token);

// Sanitize and validate the data passed in
if (isset($_POST['submit'], $_POST['username'], $_POST['email'], $_POST['p'])) {
    $email           = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING);
    $username        = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
    $new_password    = filter_input(INPUT_POST, 'new_password', FILTER_SANITIZE_STRING);
    $retype_password = filter_input(INPUT_POST, 'retype_password', FILTER_SANITIZE_STRING);
    $id              = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_STRING);
}

$new_password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
if (strlen($password) != 128) {
    // The hashed pwd should be 128 characters long.
    // If it's not, something really odd has happened
    $error_msg .= '<p class="error">Invalid password configuration.</p>';
}

$prep_stmt = "SELECT id FROM members WHERE email = ? LIMIT 1";
$stmt      = $db->prepare($prep_stmt);

if ($stmt) {
    $stmt->bind_param('s', $email);
    $stmt->execute();
    $stmt->store_result();

    if ($stmt->num_rows == 1) {
        // A user with this email address already exists
        $error_msg .= '<p class="error">A user with this email address already exists.</p>';
    }
} else {
    $error_msg .= '<p class="error">Database error</p>';
}

if ($new_password != $retype_password) {
    // Create a random salt
    $salt         = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
    // Create salted password 
    $new_password = hash('sha512', $random_salt . $salt);

}

// Insert the new hashed password into the database
if ($insert_stmt = $db->prepare("UPDATE members SET password = ? WHERE id = ?")) {
    $insert_stmt->bind_param('si', $new_password, $userID);
    // Execute the prepared query.
    if (!$insert_stmt->execute()) {
        header('Location: ../error.php?err=Database Registration failure: INSERT');
        exit();
    }

    // Update recovery key      
    if ($insert_stmt = $db->prepare("UPDATE recovery_keys SET valid = 0 WHERE userID = ? AND token = ? "));
    $insert_stmt->bind_param('is', $userID, $token);
    // Execute the prepared query.
    if ($insert_stmt->execute())
        $msg = 'Your password has changed successfully. Please login with your new password.';

} else {
    $msg = "Password doesn't match";

    header('Location: ../error.php?err=Registration failure in updating recovery key: INSERT');
    exit();
}

?>

您需要了解的重要事项。

更新here's the link

准备好的陈述:link here

密码哈希:link here

你的哈希方法非常简单,php确实提供了更好更安全的方法,请点击上面的链接。