密码哈希返回false

时间:2014-06-25 18:06:25

标签: php mysql pdo

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

<?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语句。有任何想法吗?我很新。任何安全提示都会很棒。提前致谢。

更新代码

    <?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();
}
?>

1 个答案:

答案 0 :(得分:1)

再次查看您的查询:

SELECT password FROM users WHERE email = :email

您正在选择列密码

当您获取正在使用字段hash

的行时
$_SESSION['hash'] = $row1['hash'];

与您的想法不同,您的脚本根本不简单,您在同一记录上执行3次查询,尝试此方法

$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();
}