所以我有一个简单的登录脚本,但是当我开始加密密码并使用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();
}
?>
答案 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();
}