Php 另一个密码\u verify()问题可能与数据库有关

Php 另一个密码\u verify()问题可能与数据库有关,php,mysql,passwords,Php,Mysql,Passwords,在发布之前,我已经浏览了一堆其他问题。在这一点上,我已经厌倦了把头撞在墙上。 当从注册页面移动到与数据库相关的登录页面时,似乎会出现问题 class USER { private $conn; public function __construct() { $database = new Database(); $db = $database->dbConnection(); $this->conn = $db; } public functi

在发布之前,我已经浏览了一堆其他问题。在这一点上,我已经厌倦了把头撞在墙上。 当从注册页面移动到与数据库相关的登录页面时,似乎会出现问题

class USER
{   

private $conn;

public function __construct()
{
    $database = new Database();
    $db = $database->dbConnection();
    $this->conn = $db;
}



public function register($fname,$l_init,$umail,$upass)
{
    try
    {
        $new_password = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $this->conn->prepare("INSERT INTO users(first_name,last_initial,email,salt) 
                                                   VALUES(:fname, :l_init, :umail, :upass)");

        $stmt->bindparam(":fname", $fname);
        $stmt->bindparam(":l_init", $l_init);
        $stmt->bindparam(":umail", $umail);
        $stmt->bindparam(':upass', $new_password);                                        



        if(password_verify($upass, $new_password))
        {
            $stmt->execute();
            echo "password verify works"; //$stmt->rowCount();
        }
        else
        {
            echo "password verify is corrupt";
            sleep(5);
            die;
        }
        //$resp = $stmt->fetch(PDO::FETCH_ASSOC);   

        /*if($stmt->rowCount() == 1)
        {
            $success = "New User created! Redirecting....";
        }
        else
        {
            $success = false;
        }

        return $success;    */
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }               
}


public function doLogin($umail,$upass)
{
    try
    {
        $stmt = $this->conn->prepare("SELECT * FROM users WHERE email=:umail");
        //bind params here
        $stmt->bindparam(":umail", $umail);


        $stmt->execute(); 

        echo $stmt->rowCount(); //echo if there is a returned result row

        $resp = $stmt->fetch(PDO::FETCH_ASSOC);


// checking for any variance between single/double quotes
        $one = $resp["salt"];
        $two = $resp['salt'];

        echo "first check".$one;
        echo "<br> second check" . $two . "<br>";

        //original check for existance of a match
        if($stmt->rowCount() == 1)
        {   session_start();

            echo "third check" . $upass  . '<br>';              
            echo "4th check" . password_verify($upass, $resp['salt']) . '<br>';


        echo "hash gen" . password_hash($upass, PASSWORD_DEFAULT) . '<br>';
        if($resp['salt'] == password_hash($upass, PASSWORD_DEFAULT))
            {echo "true somehow";}
        sleep(20);


            if(password_verify($upass, $resp['salt']))
            {
                session_start();
                $_SESSION['user_session'] = $resp['first_name'];
                return true;
            }
            else
            {
                return false;
            } 
        }
        else
        {
        $e_response = "Were sorry but that email is not Registered <br> Please check your spelling and try again";
        return $e_response;
        }
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
}
我整晚都在想我可能做错了什么。 我有一个可以识别密码的原始数据库用户,但是该哈希不是在SQL查询中动态创建的。它已创建并手动复制到数据库中。 请帮忙

echo password_verify("",'$2y$10$HwC2tF1hELiqJ2QEL8Oeju1L3Ore26GSnxh6CiibPbiNwPIpVUIfi')."\n";
返回1

表示在register()中传递的$upass为空

鉴于您的代码如此混乱,难怪在某个地方遗漏了它。

一些观察结果:

  • 使用密码\u散列而不是试图重新设计密码安全性对您很有好处

  • 您已经向我们展示了
    register()
    doLogin()
    的函数,但是您没有向我们展示如何调用这些函数。似乎调用它们时使用的参数不正确。调试时,回显或转储明文密码以确保具有您认为具有的值是无害的

  • 每次使用相同的明文密码调用password_hash()都会生成不同的散列值:password_hash()生成并使用一个cryptorandom salt(以减缓试图使用查找表破解密码系统的网络罪犯)

  • password_verify()函数返回true或false

  • 哈希密码包含
    $
    字符。因此,如果在php中将它们作为常量写入,则必须将它们括在单引号中,因为php尝试在字符串中用双引号替换变量

  • 但是:这不是你的问题。你的程序中没有任何包含哈希密码的字符串常量。在这里,你试图在数组元素的名称中使用单引号或双引号。在这种情况下,这种选择不会产生影响

        $one = $resp["salt"];
        $two = $resp['salt'];
    
  • 我希望您表中的哈希密码列名为
    hashed\u password
    而不是
    salt
    。因此,我在阅读您的代码时经历了几分钟的困惑,两年后当您再次使用此代码时,您也会感到困惑。如果有人维护您的代码,她会因为这种情况而诅咒您的名字g、 这种代码是长期存在的:精心构建

  • 明智的程序员避免使用
    SELECT*
    。最好给出所需列的名称。在系统的早期,尤其是在向关键表添加新列之前,这一点更为正确


  • var\u dump()
    您的第四次检查,确保它是否失败。bool(false)第四次检查呜呜!谢谢您,先生。原来我的表单中有一个简单的输入错误,变量没有传递,而是一个空字符串。(在此处插入facepalm)我现在将清理代码
        $one = $resp["salt"];
        $two = $resp['salt'];