密码哈希返回假 [英] Password hash returning false

查看:67
本文介绍了密码哈希返回假的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个简单的登录脚本,但是当我开始加密密码并使用password_verify时,我似乎一直都得到相同的结果,false.这是我的登录脚本

So I have a simple login script, but when I started encrypting passwords and using password_verify I seem to get the same result all the time, false. Here's my login script

<?php

session_start();

$host = "localhost";
$user = "root";
$pass = "root";
$dbname = "users";

try{
        $con = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);    
    $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
    echo $e->getMessage();
}
$email = htmlspecialchars($_POST['email'], ENT_QUOTES, 'UTF-8');
$pass = htmlspecialchars($_POST['password'], ENT_QUOTES, 'UTF-8');


 $st = $con->prepare("SELECT * FROM users WHERE email = :email AND password = :pass");
 $st->bindValue(':email', $email, PDO::PARAM_STR);
$st->bindValue(':pass', $pass, PDO::PARAM_STR);
$st->execute();

$rows = $st->fetch(PDO::FETCH_NUM);

if($email === ''){
$_SESSION['message1'] = 'Enter a valid email';
header('Location: index.php');
exit();
}
elseif($pass === ''){
$_SESSION['message1'] = 'Enter a valid password';
header('Location: index.php');
exit();
}
elseif($rows > 0){
    $_SESSION['loggedin'] = true;
$hash = $con->prepare("SELECT password FROM users WHERE email = :email");
$hash->bindValue(':email', $email);
$hash->execute();

}
elseif(password_verify($pass, $hash)){
    $name = $con->prepare("SELECT name FROM users WHERE email = :email");
    $name->bindValue(':email', $email, PDO::PARAM_STR);
    $name->execute();
    $rows = $name->fetchAll(PDO::FETCH_ASSOC);
    foreach ($rows as $row) {
         $_SESSION['name'] = $row['name'];
    }
    header('Location: profile.php');
     }
else{
    $_SESSION['message1'] = 'Make sure email and password are correct';
    header('Location: index.php');
    exit();
}
 ?>

这也是我加密的方式

    $passh = password_hash($pass, PASSWORD_DEFAULT)."\n";
    $db = $con->prepare("INSERT INTO users (name, email, password) VALUES (:name, :email, :passh)");
    $db->bindValue(':name', $name, PDO::PARAM_STR);
    $db->bindValue(':email', $email, PDO::PARAM_STR);
    $db->bindValue(':passh', $passh, PDO::PARAM_STR);
    $db->execute();
    $_SESSION['name'] = $name;
    $_SESSION['email'] = $email;
    $_SESSION['loggedin'] = true;
    header('Location: profile.php');
    exit();

启用了错误报告,但是由于某些原因它仍然无法正常工作,仅显示Make sure email and password are correct,该错误来自下一个else语句.有任何想法吗?我是新来的.同样,任何安全提示都将是很棒的.提前致谢.

Error reporting is enabled, but for some reason its still not working and simply displays Make sure email and password are correct, which come from the next else statement. Any ideas? I'm fairly new. Also any security tips would be great. Thanks in advance.

更新代码

    <?php

session_start();

$host = "localhost";
$user = "root";
$passw = "root";
$dbname = "users";

try{
    $con = new PDO("mysql:host=$host;dbname=$dbname", $user, $passw);   
    $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
    echo $e->getMessage();
}
$email = htmlspecialchars($_POST['email'], ENT_QUOTES, 'UTF-8');
$pass = htmlspecialchars($_POST['password'], ENT_QUOTES, 'UTF-8');



$hash = $con->prepare("SELECT password FROM users WHERE email = :email");
$hash->bindValue(':email', $email);
$hash->execute();
$rows1 = $hash->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows1 as $row1) {
     $_SESSION['hash'] = $row1['hash'];
     }



$st = $con->prepare("SELECT * FROM users WHERE email = :email AND password = :pass");
$st->bindValue(':email', $email, PDO::PARAM_STR);
$st->bindValue(':pass', $pass, PDO::PARAM_STR);
$st->execute();

$rows = $st->fetch(PDO::FETCH_NUM);

if($email === ''){
    $_SESSION['message1'] = 'Enter a valid email';
    header('Location: index.php');
    exit();
}
elseif($pass === ''){
    $_SESSION['message1'] = 'Enter a valid password';
    header('Location: index.php');
    exit();
}
elseif($rows > 0 || password_verify($pass, $hash) ){
    $_SESSION['loggedin'] = true;
    $name = $con->prepare("SELECT name FROM users WHERE email = :email");
    $name->bindValue(':email', $email, PDO::PARAM_STR);
    $name->execute();
    $rows = $name->fetchAll(PDO::FETCH_ASSOC);
    foreach ($rows as $row) {
         $_SESSION['name'] = $row['name'];
    }
    header('Location: profile.php');
    }
else{
    $_SESSION['message1'] = 'Make sure email and password are correct';
    header('Location: index.php');
    exit();
}
?>

推荐答案

再查询一次您的查询:

SELECT password FROM users WHERE email = :email

您正在选择列密码,

在获取行时,您正在使用字段hash

when you fetch the row you are using the field hash

$_SESSION['hash'] = $row1['hash'];

不同于您的想法,您的脚本根本不简单,您正在同一条记录上执行3个查询,请尝试这种方法

Unlike you think, your script is not simple at all, you are performing 3 queries on the same record, try this approach

$email = $_POST['email'];
$pass = $_POST['password'];

if($email === ''){
    $_SESSION['message1'] = 'Enter a valid email';
    header('Location: index.php');
    exit();
}

if($pass === ''){
    $_SESSION['message1'] = 'Enter a valid password';
    header('Location: index.php');
    exit();
}

$query = 'SELECT name, email, password 
          FROM users 
          WHERE email = :email LIMIT 1';


$stmt = $con->prepare($query);
$stmt->bindValue(':email', $email);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);

if(!$row){
    $_SESSION['message1'] = 'User does not exist';
    header('Location: index.php');
    exit();
}

//hashed password from Database
$hash = $row['password'];

if(password_verify($pass, $hash)){
    $_SESSION['hash'] = $row['password'];
    $_SESSION['name'] = $row['name'];
    $_SESSION['email'] = $row['email'];
    header('Location: profile.php');
}else{
    $_SESSION['message1'] = 'Make sure email and password are correct';
    header('Location: index.php');
    exit();
}

这篇关于密码哈希返回假的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆