[mysql]返回 false 的密码哈希

标签: MySQL PHP
发布时间: 2017/1/11 19:18:33
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

所以我有一个简单的登录脚本,但当我开始加密的密码和使用 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:

一个更多的时间来看您的查询︰

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();
}
官方微信
官方QQ群
31647020