PHP密码\u验证与哈希不匹配
所以我有两个注册和登录的功能。注册工作正常,用户表被填充,散列存储在user\u pass列中,等等。登录时,我不断收到“error Details”错误消息。密码\u verify似乎与输入的密码不匹配。你们能看到我的代码有什么问题吗?我在这里挠头PHP密码\u验证与哈希不匹配,php,hash,password-encryption,Php,Hash,Password Encryption,所以我有两个注册和登录的功能。注册工作正常,用户表被填充,散列存储在user\u pass列中,等等。登录时,我不断收到“error Details”错误消息。密码\u verify似乎与输入的密码不匹配。你们能看到我的代码有什么问题吗?我在这里挠头 public function register($uname,$umail,$upass) { try { $new_password = password_hash($upass, PASSWORD_DEFAUL
public function register($uname,$umail,$upass)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("INSERT INTO users(user_name,user_email,user_pass)
VALUES(:uname, :umail, :upass)");
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function doLogin($uname,$umail,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass FROM users WHERE user_name=:uname OR user_email=:umail ");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
rowCount()
不返回SELECT
语句中的行数。无需测试以查看查询是否成功,您可以向右移动以测试密码:
public function doLogin($uname,$umail,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass FROM users WHERE user_name=:uname OR user_email=:umail ");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
您是否验证了散列的结果与存储在DB中并返回的结果相同
var_dump()
返回password_hash()
和user_pass
列的结果并进行比较。I var_转储$new_密码及其字符串(60)“$2y$10$ygo1AxF4shtgslmtblqseeS0foau0yyy3.hX/X4.bbjjerufa9h9s”然后我检查了数据库列,它是$2y$10$Ygo1AXF4shTgslmTbLqSeeS0fOAU0Yy3.hX/X4.BBJJEYRUFA9H9SY,你需要养成这样的习惯来帮助你解决问题。您将获得积分,并鼓励其他人帮助您。您是否验证了$stmt->fetch()
实际上会返回您想要的记录?执行var\u dump($userRow)
确实很有帮助。实际上,不检查数据就继续进行操作是不安全的。首先,没有验证,检索到了超过1条记录,这对于所提出的算法来说是一个混乱的情况,因为不清楚作者需要登录哪个用户。第二,当没有检索到任何记录时,将访问FALSE['user\u pass']
,这将导致错误警告(除非框架是一个蹩脚的框架,否则只会使其静音)。至少应该有if($userRow)
check present。这是一个关于这是否安全的混合包@AndreyTserkus如果没有行将抛出错误。如果OP确保表中包含唯一的值(他应该这样做),则users
表中永远不会有超过一行的ID有问题。我们无法为他们编写所有的代码,但感谢DV-我会考虑你在回答这个问题时所说的话。好吧,那里的检查是故意的。因此,正确的建议应该是建议使用正确的函数,而不仅仅是删除不正确的函数。我们必须同意不同意@AndreyTserkus。除了MySQL API的旧版本外,我参与的所有系统都没有执行过这种检查。这是一个不必要的检查,不需要替换,因为查询(针对我前面提到的正确设置的数据库)要么返回结果,要么不返回结果。OP用返回false来处理该问题代码>继续下去没有意义。这条线我用完了。