簡體   English   中英

Mysqli:我無法使用散列密碼登錄

[英]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 子句匹配的所有內容,即studnopassword因此這永遠不會用作來自用戶的密碼未經過哈希處理,因此它永遠不會匹配經過哈希處理的密碼。 您需要從 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM