[英]Forgot password email reset php works, except neither original nor changed password allow login
我為我的登錄系統創建了一個忘記密碼更改php功能,該功能向忘記了密碼的用戶發送電子郵件,並使用哈希標記提供鏈接以更改密碼。 一旦用戶選擇了電子郵件鏈接,他們就可以更改密碼,然后使用新的哈希密碼更新mysql。
在我嘗試使用新密碼登錄之前,代碼的每個方面似乎都能正常工作。 我收到“用戶名/密碼組合不正確”的回聲(在LOGIN.PHP頁面上找到)。 嘗試使用原始密碼在LOGIN.PHP頁面上也會出現相同的錯誤。
不完全確定為什么我的SQL查詢與更新的密碼與現有用戶名不匹配並允許登錄?
為了便於通過代碼解析,我排除了我認為不是問題的部分。 我已經包含了5個php文件。
FORGOTPASSWORD.PHP
<?php
if (!isset($_GET['email'])) {
echo '<form action="">//Form for password reset here</form>';
exit();
}
define('DB_USER', '');
define('DB_PASS', '');
define('DB_NAME', '');
$email = $_GET['email'];
function connect()
{
//Connect to db
}
connect();
$q = "SELECT email FROM users WHERE LCASE(TRIM(email))='" . strtolower(trim($email)) . "'";
$r = mysql_query($q);
$n = mysql_num_rows($r);
if ($n == 0) {
echo "Email id is not registered";
die();
}
//token updated into sql db for user
$token=getRandomString(10);
$q="UPDATE users SET token=('".$token."') WHERE email=('".$email."')";
mysql_query($q);
function getRandomString($length)
{
//token created
}
//email creation code here
RESET.PHP
<?php
session_start();
//Define db connection parameters
$token=$_GET['token'];
function connect() {
//Connection to db executed
}
connect();
if(!isset($_POST['password'])){
$q="SELECT email FROM users WHERE token='".$token."' and used='0'";
$r=mysql_query($q);
while($row=mysql_fetch_array($r))
{
$email=$row['email'];
}
If ($email!=''){
$_SESSION['email']=$email;
}
else die("Invalid link or Password already changed");}
$password=$_POST['password'];
$email=$_SESSION['email'];
if(!isset($password)){
echo '
//Change password form
';}
if(isset($_POST['password'])&&isset($_SESSION['email']))
{
//Update sql db with newly created password
$q="UPDATE users SET password='".md5($password)."' WHERE email='".$email."'";
$r=mysql_query($q);
if($r)mysql_query("UPDATE users SET used='1' WHERE token='".$token."'");echo "Your password is changed successfully";
if(!$r)echo "An error occurred";
}
?>
LOGIN.PHP(顯示錯誤消息)
<div id="loginContainer">
<div id="loginMessage">
<?php if ( $logged == 'invalid' ) : ?>
<p class="name_pass">
The username/password combination is incorrect. Try again.
</p>
<?php endif; ?>
<?php if ( $_GET['reg'] == 'true' ) : ?>
<p class="success">Your registration was successful, please login below.
</p>
<?php endif; ?>
<?php if ( $_GET['action'] == 'logout' ) : ?>
<?php if ( $loggedout == true ) : ?>
<p class="log_out">You have been successfully logged out.
</p>
<?php else: ?>
<p class="problem">There was a problem logging you out.
</p>
<?php endif; ?>
<?php endif; ?>
<?php if ( $_GET['msg'] == 'login' ) : ?>
<p class="must_login">You must login to view this content. Please login below.
</p>
<?php endif; ?>
</div>
CLASS.PHP(登錄功能)
function login($redirect) {
global $jdb;
if ( !empty ( $_POST ) ) {
$values = $jdb->clean($_POST);
$subname = $values['username'];
$subpass = $values['password'];
$table = 'users';
$sql = "SELECT * FROM $table WHERE username = '" . $subname . "'";
$results = $jdb->select($sql);
if (!$results) {
die('Sorry, that username does not exist!');
}
$results = mysql_fetch_assoc( $results );
$storeg = $results['date'];
$stopass = $results['password'];
$nonce = md5('registration-' . $subname . $storeg . NONCE_SALT);
$subpass = $jdb->hash_password($subpass, $nonce);
if ( $subpass == $stopass ) {
$authnonce = md5('cookie-' . $subname . $storeg . AUTH_SALT);
$authID = $jdb->hash_password($subpass, $authnonce);
setcookie('logauth[user]', $subname, 0, '', '', '', true);
setcookie('logauth[authID]', $authID, 0, '', '', '', true);
$url = "http" . ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$redirect = str_replace('login.php', $redirect, $url);
header("Location: $redirect");
exit;
} else {
return 'invalid';
}
} else {
return 'empty';
}
}
INDEX.PHP(成功登錄后登陸頁面)
<?php
require_once('load.php');
$logged = $j->checkLogin();
if ( $logged == false ) {
//Build our redirect
$url = "http" . ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$redirect = str_replace('index.php', 'login.php', $url);
//Redirect to the home page
header("Location: $redirect?msg=login");
exit;
} else {
//Grab our authorization cookie array
$cookie = $_COOKIE['logauth'];
//Set our user and authID variables
$user = $cookie['user'];
$authID = $cookie['authID'];
//Query the database for the selected user
$table = 'users';
$sql = "SELECT * FROM $table WHERE username = '" . $user . "'";
$results = $jdb->select($sql);
//Kill the script if the submitted username doesn't exit
if (!$results) {
die('Sorry, that username does not exist!');
}
//Fetch our results into an associative array
$results = mysql_fetch_assoc( $results );
?>
感謝您的幫助。 我感謝任何願意看一下代碼的人,以幫助我弄清楚我的登錄過程的最后一部分。 謝謝。
在您的reset.php文件中,您存儲了密碼的未加密版MD5 ...
$password=$_POST['password'];
$q="UPDATE users SET password='".md5($password)."' WHERE email='".$email."'";
...但是你把它與不同的東西進行比較......
$subpass = $values['password']; // seems to be the entered password
...
$stopass = $results['password']; // seems to be the stored MD5 password hash
...
$subpass = $jdb->hash_password($subpass, $nonce); // probably not an unsalted MD5
if ( $subpass == $stopass ) // comparison of different things
即使您使用此代碼,它也將是一個非常不安全的解決方案。 相反,您應該絕對切換到PHP中內置的密碼哈希函數。 DB字段應該是varchar(255)
,代碼可能看起來像這樣:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);
$q="UPDATE users SET password='".$hashToStoreInDb."' WHERE email='".$email."'";
要檢查密碼,您需要從數據庫中獲取哈希值並將其與password_verify進行比較,因此將使用與用於存儲哈希值相同的鹽進行比較。
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $stopass.
$subpass = $values['password'];
...
$stopass = $results['password'];
...
$isPasswordCorrect = password_verify($subpass, $stopass);
if ($isPasswordCorrect)
您的代碼中的另一個問題是SQL注入,您可以使用預准備語句來避免這種漏洞。 您可以在另一個答案中找到MySqli或PDO的示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.