简体   繁体   English

password_verify即使使用适当的变量,也始终返回False

[英]password_verify Always Returns False, even with proper variables used

My webpage starts with a login page, like many, and if the user has no account they can sign up. 我的网页从许多登录页面开始,如果用户没有帐户,则可以注册。 My sign up works and the users password they input is successfully hashed with password_hash and sent to the database. 我的注册成功了,他们输入的用户密码已成功用password_hash进行了哈希处理并发送到了数据库。 However, when trying to login, password_verify always returns false. 但是,尝试登录时, password_verify始终返回false。 Thinking I made a silly error when I originally made the hashed password, I echoed the variable I was using as the second parameter in password_verify . 当我最初创建哈希密码时,以为我犯了一个愚蠢的错误,我回显了我用作password_verify第二个参数的变量。 However, it was an exact match to the hash in the database. 但是,它与数据库中的哈希完全匹配。 What could be the issue?? 可能是什么问题?? Shortened code is available below for both creating the password during sign up and checking the password while logging in. 下面提供了缩短的代码,可用于在注册期间创建密码和在登录时检查密码。

CREATING HASHED PASSWORD 创建哈希密码

<?php
    session_start();
    require('db_credentials.php');

    $inputUsername = $_POST['createUsername'] ? $_POST['createUsername'] : null;
    $inputPassword = $_POST['createPassword'] ? $_POST['createPassword'] : null;
    $vPassword = $_POST['verifyPassword'] ? $_POST['verifyPassword'] : null;

     //protect database from corrupt user input
    $inputUsername = $mysqli->real_escape_string($inputUsername);
    $inputPassword = $mysqli->real_escape_string($inputPassword);
    $vPassword = $mysqli->real_escape_string($vPassword);

    //create connection
    $mysqli = new mysqli($servername, $username, $password, $dbname);

    $protectedPassword = password_hash($inputPassword, PASSWORD_DEFAULT);

    //Check if the passwords match
if($inputPassword != $vPassword){
    echo '<p style = "text-align: center;">Oops!The passwords you input did not match. Please try again.</p>';
    session_write_close();
    exit;
}

//Check for duplicate username
$query = "SELECT * FROM user_info WHERE username = ' ".$inputUsername." ' ";
$result = mysqli_query($mysqli, $query);

if(mysqli_num_rows($result) == 1) {
    echo '<p style = "text-align: center;">Oops! That Username is already taken. <br>Please try a different one.</p>';    
    session_write_close();
    exit;
}
//Username is not takin and the passwords match
else {
    $sql = "INSERT INTO user_info (username, password) VALUES (' ".$inputUsername." ', ' ".$protectedPassword." ')";
    echo '<p style = "text-align: center;">Success! You Have Made an Account!</p>';
    if($mysqli->query($sql) === TRUE) {
        session_write_close();
        exit;
    }
     else {
         echo "Error: " . $sql . "<br>" . $conn->error;
    }
}
?>

LOGGING IN 在登录

<?php

    require('db_credentials.php');

    $inputUsername = $_POST['username'] ? $_POST['username'] : null;
    $inputPassword = $_POST['password'] ? $_POST['password'] : null;
    //protect database from corrupt user input
    $inputUsername = $mysqli->real_escape_string($inputUsername);
    $inputPassword = $mysqli->real_escape_string($inputPassword);

    $mysqli = new mysqli($servername, $username, $password, $dbname);        

    $query = "SELECT * FROM user_info WHERE username = ' ".$inputUsername." ' ";
    $result = $mysqli->query($query);

    //check if username is in database. If it is, do the passwords match?
    if($result->num_rows === 1) {

        $row = $result->fetch_array(MYSQLI_ASSOC);
        echo $row['password'] . "<br>"; //matches hash in database exactly
        echo $inputPassword; //matches the password I type in. Which is same I used to sign up.
        if(password_verify($inputPassword, $row['password'])){
            header("Location: puzzlerMember.php"); //this never happens
            exit; 
        }

    }    
    echo '<p style = "text-align: center;">Oops! Your Username/Password is incorrect. Sign up if you do not have an account.</p>'; //this always happens
    exit;

?>

Note: In the database, I have the password column set to VARCHAR(255). 注意:在数据库中,我将密码列设置为VARCHAR(255)。 I've looked at many of these questions which are similar, but they all seemed to have mistaken the length of their password in the database to be too short. 我看过许多类似的问题,但是它们似乎都把数据库中密码的长度误认为太短。 If they did not, I tried the top answer of the solutions. 如果他们没有,我尝试解决方案的最佳答案。 I have absolutely no idea what is wrong. 我完全不知道出什么问题了。 If you can help, I thank you in advance. 如果可以的话,我先谢谢您。

You are escaping your password, as a result this changes the password from what it was. 您正在转义密码,其结果是更改了原来的密码。 Instead of relying on escaping as a security measure (which in itself is a misconception), use prepared statements. 不要使用转义作为安全措施(这本身就是一种误解),而应使用准备好的语句。

As per the comment below, a clarification is required it seems: You are escaping the password then hashing it, as a result what is stored in the db is not what the user passes therefore it will never find what the user passes, hence, false is always returned. 根据下面的评论,似乎需要澄清:您在转义密码然后对其进行哈希处理,结果是数据库中存储的内容不是用户通过的内容,因此它将永远找不到用户通过的内容,因此为false总是返回。

Related: Should I mysql_real_escape_string the password entered in the registration form? 相关: 我应该在mysql_real_escape_string注册表中输入密码吗?

Update #1 更新#1

As spotted by @mario, you seem to have spaces in your query when you are passing the values to it as such, it is searching your table for incorrect values. 正如@mario所发现的那样,当您将值传递给查询时,查询中似乎有空格,这是在表中搜索错误的值。

Reading Material 阅读材料

Prepared Statements 准备的陈述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM