簡體   English   中英

忘記密碼電子郵件重置php工作,除了原始或更改密碼都不允許登錄

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM