Mysqli:我无法使用哈希密码登录

时间:2017-01-29 13:45:59

标签: php html mysqli bcrypt

我使用mysqli和hashpassword。 我无法使用密码登录,但我不知道原因。 我尽我所能,但根本没有工作。

我在我的数据库中使用utf8。

这是我的regiter 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");
    }
}

3 个答案:

答案 0 :(得分: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文件,其中创建会话并存储当前登录的用户数据)。您的注册页面应该检查登录用户以及登录页面(为什么登录或注册,如果已经登录?),因此您需要在某个地方全局启动会话。

答案 1 :(得分:0)

您正在使用相同的哈希验证相同的密码。使用

 password_verify($password, $dbpassowrd);

您的代码很容易受到SQL注入攻击。验证它,清理用户输入并使用准备好的staments。

答案 2 :(得分:0)

你需要做的很简单。您的代码永远不会返回结果这一原因"SELECT * FROM users WHERE studno='".$studno."' AND password='".$password."'"这将永远不会返回任何结果,因为您在注册时已将密码保存为哈希,现在当用户登录时选择了来自users表的匹配where子句的所有内容(studnopassword因此,这将永远不会起作用,因为来自用户的密码未加扰,因此它将永远不会与散列密码匹配。您需要从where子句中删除密码,并且只在where子句中包含id。

同样这是错误的password_verify($dbpassword,$row['password']))记住$ dbpasssword和$row['password']是相同的,记住你在脚本$dbpassword=$row['password'];中有这个,所以基本上你的password_verify()正在读这样的{ {1}}您正在针对相同的存储哈希验证存储的哈希。 password_verify()应始终如下所示:password_verify(storedHash,storedHash)您必须根据存储的哈希值从用户输入验证密码。

所以说过你的脚本看起来应该类似于:

password_virify(PasswordFromTheUserInput,StoredHash)

希望这有所帮助,我可能错过了一些东西,但逻辑应该与上面相同,我对mysqli不太好,我大部分时间都使用PDO。

注意:请考虑@John Smith的答案,他提出了非常重要的一点,你需要申请。