我为我的登录系统创建了一个忘记密码更改的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 );
?>
感谢您的帮助。我感谢任何愿意看一下代码的人,以帮助我弄清楚我的登录过程的最后一部分。 感谢。
答案 0 :(得分:0)
在您的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注入,您可以使用预准备语句来避免这种漏洞。您可以在另一个answer中找到MySqli或PDO的示例。