我的注册脚本接受用户的密码,然后使用PHP的password_hash函数对密码进行加密,然后将其放入数据库中。当我使用刚刚创建的用户登录时,出现了检查密码是否相同的错误。就我而言,不是。在登录脚本中调用password_verify函数时,我在做什么错?
寄存器
if($_SERVER["REQUEST_METHOD"] == "POST"){ function secure($data){ $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return($data); } $p_num = secure($_POST["p_number"]); $first_name = secure($_POST["first_name"]); $last_name = secure($_POST["last_name"]); $email = secure($_POST["email"]); $password = secure($_POST["pw"]); $verify_password = secure($_POST["pw_verify"]); $program = secure($_POST["program"]); $role = secure($_POST["role"]); $logged_in = 0; $registered = 0; $image = "../images/profile_placeholder.png"; if($password != $verify_password){ echo "Nope. Passwords"; } else{ $registered = 1; $password = password_hash($password, PASSWORD_DEFAULT); $insert = "INSERT INTO `$user_table`(`user_id`, `first_name`, `last_name`, `password`, `image`, `email`, `program`, `role`, `logged_in`, `registered`) VALUES('" .$p_num ."', '" .$first_name ."', '" .$last_name ."', '" .$password ."', '" .$image ."', '" .$email ."', '" .$program ."', '" .$role ."', '" .$logged_in ."', '" .$registered ."')"; $query = mysqli_query($connect, $insert); echo "Success!"; } }
登录
if($_SERVER["REQUEST_METHOD"] == "POST"){ $p_num = $_POST["username"]; $pwd = $_POST["password"]; $query = "SELECT * FROM `$user_table` WHERE `user_id` = '$p_num'"; $result = mysqli_query($connect, $query); while($row = mysqli_fetch_assoc($result)){ $user_id = "{$row['user_id']}"; $first_name = "{$row['first_name']}"; $last_name = "{$row['last_name']}"; $user_name = $first_name ." " .$last_name; $password = "{$row['password']}"; $image = "{$row['image']}"; $email = "{$row['email']}"; $program = "{$row['program']}"; $role = "{$row['role']}"; $status = "{$row['logged_in']}"; $registered = "{$row['registered']}"; if(($user_id == $p_num) && (password_verify($pwd, $password))){ $_SESSION["id"] = $user_id; $_SESSION["user"] = $user_name; $_SESSION["program"] = $program; $_SESSION["pass"] = $password; $_SESSION["image"] = $image; $_SESSION["email"] = $email; $_SESSION["role"] = $role; $_SESSION["status"] = $status; $_SESSION["registered"] = $registered; $loggedin = "UPDATE `$user_table` SET `logged_in` = 1 WHERE `user_id` = '$user_id'"; } var_dump($pwd); var_dump($password); }
这是我执行var_dump时得到的:
string(1) "1" string(16) "$2y$10$0aysCso3b"
很明显,密码没有匹配在一起。因此,在注册脚本上,密码被散列并发送到数据库。然后,当用户登录时,登录脚本会查看用户输入的登录密码,然后使用password_verify将其与数据库中的哈希密码进行比较。但是,哈希密码不接受未哈希的密码作为匹配项。我不明白的是,为什么?
这是我用于password_hash和的内容password_verify。以书面形式尝试一下,一旦成功,您就可以开始添加其余代码。
password_hash
password_verify
修改表和列的名称以适合。
注意: 这是基本的插入方法。我建议您改用 准备好的语句 。
旁注:password列的长度必须足以容纳hash VARCHAR(255)。请查阅“脚注”。
VARCHAR(255)
插入文件
<?php $DB_HOST = 'xxx'; $DB_USER = 'xxx'; $DB_PASS = 'xxx'; $DB_NAME = 'xxx'; $conn = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); if($conn->connect_errno > 0) { die('Connection failed [' . $conn->connect_error . ']'); } $password = "rasmuslerdorf"; $first_name = "john"; $password = password_hash($password, PASSWORD_DEFAULT); $sql = "INSERT INTO users (`name`, `password`) VALUES ('" .$first_name ."', '" .$password ."')"; $query = mysqli_query($conn, $sql); if($query) { echo "Success!"; } else{ // echo "Error"; die('There was an error running the query [' . $conn->error . ']'); }
登录文件
<?php // session_start(); $DB_HOST = 'xxx'; $DB_USER = 'xxx'; $DB_PASS = 'xxx'; $DB_NAME = 'xxx'; $conn = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME); if($conn->connect_errno > 0) { die('Connection failed [' . $conn->connect_error . ']'); } $pwd = "rasmuslerdorf"; $first_name = "john"; //$sql = "SELECT * FROM users WHERE id = 1"; $sql = "SELECT * FROM users WHERE name='$first_name'"; $result = $conn->query($sql); if ($result->num_rows === 1) { $row = $result->fetch_array(MYSQLI_ASSOC); if (password_verify($pwd, $row['password'])) { //Password matches, so create the session // $_SESSION['user'] = $row['user_id']; // header("Location: http://www.example.com/logged_in.php"); echo "Match"; }else{ echo "The username or password do not match"; } } mysqli_close($conn);
脚注:
密码列应足够长以容纳哈希。哈希产生的字符长度为72 long,但手册建议为255。
参考:
“使用bcrypt算法(PHP 5.5.0的默认值)。请注意,此常数旨在随着时间的推移而变化,因为向PHP添加了新的更强大的算法。因此,使用此标识符的结果长度可能会改变因此,建议将结果存储在数据库列中,该列可以扩展到超过60个字符(255个字符是一个不错的选择)。”