gpt4 book ai didi

php - 在登录脚本中将 password_verify 放在哪里?

转载 作者:可可西里 更新时间:2023-11-01 13:46:58 24 4
gpt4 key购买 nike

又是一个晚上,又是一个问题!

我已经创建了一个登录页面,如果密码是纯文本,它可以正常工作。

我遇到的问题是我的注册表单使用 password_hash 向表格输入加密密码。

我当前的脚本如下。

Sign Up Script

$password = password_hash($_POST['password'], PASSWORD_DEFAULT);

Log In Script

<?php
session_start();
if(isset($_POST['email'], $_POST['password'])){
require('../../../private_html/db_connection/connection.php');
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$query = $conn->prepare("SELECT * FROM user_accounts WHERE email=:email AND password=:password");
$query->bindParam(':email', $_POST['email']);
$query->bindParam(':password', $_POST['password']);
$query->execute();

if($row = $query->fetch()){
$_SESSION['email'] = $row['email'];
$_SESSION['first_name'] = $row['first_name'];
header("Location: ../../myaccount/myaccount.php");
}
else {header("Location:../../login/login.php ");}
}

?>

关于这个我有几个问题:

  1. 我应该将 password_verify 放在登录脚本的什么位置?
  2. 不必输入多个 $_SESSION['xxx'] = $row['xxx']; 来在“我的帐户”页面上显示用户详细信息,我如何利用我读过的 $results = $stmt->fetch(PDO::FETCH_ASSOC); 方法?

非常感谢,

西里尔海象

最佳答案

阅读代码之前,请记住 Fake Registration block 不会在您的代码中,但有必要端到端地向您展示这一点。

<?php
session_start();
// Begin Vault
// credentials from a secure Vault, not hard-coded
$servername="localhost";
$dbname="login_system";
$username="dbUserName";
$password="dbPassword";
// End Vault

// The following two variables would come from your form, naturally
// as $_POST[]
$formEmail="jsmith123@gmail.com";
$ctPassword="¿^?fish╔&®)"; // clear text password

try {
#if(isset($_POST['email'], $_POST['password'])){
#require('../../../private_html/db_connection/connection.php');
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Begin Fake Registration
// fake it that user already had password set (from some registration insert routine)
// the registration routine had SSL/TLS, safely passing bound parameters.
$hp=password_hash($ctPassword,PASSWORD_DEFAULT); // hashed password, using
$conn->query("delete from user_accounts where email='jsmith123@gmail.com'");
$conn->query("insert user_accounts(first_name,last_name,email,password) values ('joe','smith','jsmith123@gmail.com','$hp')");
// we are done assuming we had a registration for somewhere in your system
// End Fake Registration

$query = $conn->prepare("SELECT * FROM user_accounts WHERE email=:email");
$query->bindParam(':email', $formEmail);
$query->execute();

unset($_SESSION['email']);
unset($_SESSION['first_name']);

if(($row = $query->fetch()) && (password_verify($ctPassword,$row['password']))){
$_SESSION['email'] = $row['email'];
$_SESSION['first_name'] = $row['first_name'];
//header("Location: ../../myaccount/myaccount.php");
echo "hurray, you authenticated.<br/>";
}
else {
//header("Location:../../login/login.php ");
echo "invalid login<br/>";
}
#}
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit();
}
?>

浏览器输出:

hurray, you authenticated.

请注意,password_hash() 函数使用随机盐,这一点很明显如果你多次运行它,散列密码更改使用相同的明文输入,例如这些散列密码:

$2y$10$KywNHrGiPaK9JaWvOrc8UORdT8UXe60I2Yvj86NGzdUH1uLITJv/q

$2y$10$vgJnAluvhfdwerIX3pAJ0u2UKi3J.pfvd0vIqAwL0Pjr/A0AVwatW

如前所述,这两者都是相同明文密码的后续散列的结果。 salt 和散列 cost 被烘焙到散列密码中并保存。这些电话都可以在下面的链接中阅读。

来自手册 password_hashpassword_verify .

架构

create table user_accounts
( id int auto_increment primary key,
first_name varchar(50) not null,
last_name varchar(50) not null,
email varchar(100) not null,
password varchar(255) not null
);

关于php - 在登录脚本中将 password_verify 放在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32554085/

24 4 0