[英]Mysqli: I can't login with hashed password
我正在使用帶有 hashpassword 的 mysqli。 我無法使用我的密碼登錄,我不知道為什么。 我盡了最大的努力,但它根本不起作用。
我在我的數據庫中使用 utf8。
這是我的注冊 php
<?php
if(isset($_POST["register"])){
if(!empty($_POST['name']) &&
!empty($_POST['studno']) &&
!empty($_POST['password']) &&
!empty($_POST['cpassword']) &&
!empty($_POST['email']))
{
$name=$_POST['name'];
$studno=$_POST['studno'];
$password= password_hash($_POST['password'],PASSWORD_BCRYPT);
$email=$_POST['email'];
$con=mysqli_connect('localhost','root','') or die(mysqli_error($con));
mysqli_select_db($con,'inventory') or die("cannot select DB");
$query=mysqli_query($con,"SELECT * FROM users WHERE studno='".$studno."'");
$numrows=mysqli_num_rows($query);
if($numrows==0) {
$sql = "INSERT INTO users(name,studno,email,password) "
. " VALUES('$name','$studno','$email','$password')";
$result=mysqli_query($con,$sql);
if ($_POST['password'] == $_POST['cpassword']) {
if ($result) {
header("Location: index.php?registered=1");
}
} else {
header("Location: signup.php?passwordnotmatch=1");
}
} else { /* numrows != 0 */
header("Location: signup.php?alreadyinuse=1");
}
} else {
header("Location: signup.php?allfieldisrequired=1");
}
}
?>
這是我的php登錄。
<?php
if (isset($_POST["login"])) {
if (!empty($_POST['studno']) && !empty($_POST['password'])) {
$studno=$_POST['studno'];
$password=$_POST['password'];
$con=mysqli_connect('localhost','root','') or die(mysql_error($con));
mysqli_select_db($con,'inventory') or die("cannot select DB");
$query=mysqli_query($con,"SELECT * FROM users WHERE studno='".$studno."' AND password='".$password."'");
$numrows=mysqli_num_rows($query);
if ($numrows!=0) {
while($row=mysqli_fetch_assoc($query)) {
$dbstudno=$row['studno'];
$dbpassword=$row['password'];
}
if ($studno == $dbstudno && password_verify($dbpassword,$row['password']))) {
session_start();
$_SESSION['sess_user']=$studno;
/* Redirect browser */
header("Location: home.php");
}
} else {
header("Location: index.php?error=1");
}
} else {
header("Location: index.php?missing=1");
}
}
已經有很多人對此發表了評論,但我將其作為答案發布:
您的代碼有很多問題:
1)您需要針對數據庫驗證用戶的輸入,而不是針對數據庫驗證數據庫。 這意味着以下行將起作用:
password_verify($password,$row['password'])
2)你的SQL查詢沒有任何防止sql注入的東西,查一下。
3)您的注冊頁面允許用戶迭代,查找。
4)不要使用while循環只獲取數據庫的第一行,只需使用單個mysqli_fetch_assoc,它將返回第一行。 如果您只希望得到一個結果,也可以在查詢結束時使用 LIMIT 1。
5)從數據庫中選擇時,請始終指定需要返回的列,除非您絕對確定需要返回的所有列,這將大大加快您的查詢速度。
6) 全局創建您的 mysqli 連接(例如,創建一個 database.php 文件並在那里連接到數據庫),而不是在您使用的每個 php 文件中創建一個連接。
7) 全局啟動會話(例如,創建一個 user.php 文件,在其中創建會話並存儲當前登錄的用戶數據)。 您的注冊頁面應該檢查登錄用戶,登錄頁面也是如此(如果已經登錄,為什么要登錄或注冊?)所以您需要在某個地方全局啟動會話。
您正在使用相同的哈希驗證相同的密碼。 用
password_verify($password, $dbpassowrd);
而且您的代碼很容易受到 SQL 注入攻擊。 驗證它,清理用戶輸入並使用准備好的語句。
您需要做的很簡單。 由於"SELECT * FROM users WHERE studno='".$studno."' AND password='".$password."'"
這一個原因,您的代碼永遠不會返回結果,因為您已保存注冊時將密碼作為哈希值,現在會發生什么,當用戶登錄時,您從用戶表中選擇與 where 子句匹配的所有內容,即studno
和password
因此這永遠不會用作來自用戶的密碼未經過哈希處理,因此它永遠不會匹配經過哈希處理的密碼。 您需要從 where 子句中刪除密碼,並且只有 where 子句中的 id。
這又是錯誤的password_verify($dbpassword,$row['password']))
記住 $dbpasssword 和$row['password']
是一樣的 記住你的腳本中有這個$dbpassword=$row['password'];
所以基本上你的password_verify()
password_verify(storedHash,storedHash)
像這樣password_verify(storedHash,storedHash)
你正在驗證存儲的哈希值與相同的存儲哈希值。 password_verify() 應該始終讀作: password_virify(PasswordFromTheUserInput,StoredHash)
您必須根據存儲的哈希值驗證來自用戶輸入的密碼。
因此,話雖如此,您的腳本應該與此類似:
<?php
ob_start();
session_start();
//Extract the inputs from the user
$query = ("SELECT studno,password FROM users WHERE studno='" . $studno . "'");
$result = $con->query($query);
if ($result->num_rows > 0) {
// we have the results
while ($row = $result->fetch_assoc()) {
$dbstudno = $row['studno'];
$dbpassword = $row['password'];
// check user password against stored hash
if (password_verify($password, $dbpassword)) {
// password correct start a session
$_SESSION['sess_user'] = $studno;
/* Redirect browser */
header("Location: home.php");
} else {
header("Location: index.php?error=1");
}
}
} else {
header("Location: index.php?missing=1");
}
?>
希望這會有所幫助,我可能錯過了一些東西,但邏輯應該與上述相同,我不擅長 mysqli,我大部分時間都在使用 PDO。
注意:請考慮@John Smith 的回答,他提出了您需要應用的非常重要的觀點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.