PHP使用密码加密方案的安全登录系统

时间:2018-05-16 04:12:04

标签: php mysql security login

我一直在为用户开发一个安全的登录页面,但在登录时,密码验证似乎无法正常工作。

下面的代码似乎找到了我在MySql中创建的数据库中的用户名,但主要是密码每次都不匹配。

我做了所有可能的改变,尝试了所有的建议,但仍然没有成功。如果有人对此问题有任何解决方案,我们将不胜感激。

错误始终显示密码不正确。

登录页面:

<?php
/* User login process, checks if user exists and password is correct */

// Escape email to protect against SQL injections
$username = $mysqli->escape_string($_POST['username']);
$password = $mysqli->escape_string(password_hash($_POST['password'], PASSWORD_BCRYPT));
$result = $mysqli->query("SELECT * FROM `users` WHERE `username`='$username'");

if ( $result->num_rows == 0 ){ // User doesn't exist
    $_SESSION['message'] = "User with that username doesn't exist!";
    header("location: error.php");
}
else { // User exists
    $user = $result->fetch_assoc();

    if ( password_verify($_POST['password'], $user['password']) ) {

        $_SESSION['email'] = $user['email'];
        $_SESSION['first_name'] = $user['first_name'];
        $_SESSION['last_name'] = $user['last_name'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['active'] = $user['active'];

        // This is how we'll know the user is logged in
        $_SESSION['logged_in'] = true;

        header("location: dashboard.html");
    }
    else {
        $_SESSION['message'] = "You have entered wrong password, try again!";
        header("location: error.php");
    }
}

注册页面:

<?php
/* Registration process, inserts user info into the database 
   and sends account confirmation email message
 */

// Set session variables to be used on profile.php page
$_SESSION['email'] = $_POST['email'];
$_SESSION['first_name'] = $_POST['firstname'];
$_SESSION['last_name'] = $_POST['lastname'];

// Escape all $_POST variables to protect against SQL injections
$first_name = $mysqli->escape_string($_POST['firstname']);
$last_name = $mysqli->escape_string($_POST['lastname']);
$email = $mysqli->escape_string($_POST['email']);
$password = $mysqli->escape_string(password_hash($_POST['password'], PASSWORD_BCRYPT));
$hash = $mysqli->escape_string( md5( rand(0,1000) ) );

// Check if user with that email already exists
$result = $mysqli->query("SELECT * FROM users WHERE email='$email'") or die($mysqli->error());

// We know user email exists if the rows returned are more than 0
if ( $result->num_rows > 0 ) {

    $_SESSION['message'] = 'User with this email already exists!';
    header("location: error.php");

}
else { // Email doesn't already exist in a database, proceed...

    // active is 0 by DEFAULT (no need to include it here)
    $sql = "INSERT INTO users (first_name, last_name, email, password, hash, active) " 
            . "VALUES ('$first_name','$last_name','$email','$password', '$hash', 1)";

    // Add user to the database
    if ( $mysqli->query($sql) ){

        $_SESSION['active'] = 0; //0 until user activates their account with verify.php
        $_SESSION['logged_in'] = true; // So we know the user has logged in
        $_SESSION['message'] =

                 "Confirmation link has been sent to $email, please verify
                 your account by clicking on the link in the message!";

        header("location: profile.html"); 

    }
    else {
        $_SESSION['message'] = 'Registration failed!';
        header("location: error.php");
    }
}

以下是用户登录系统时使用的登录/注册表单:“http://riselamagana.byethost4.com/projects/webdev3/production/index.php

,数据库将是: table "users"

为“password_28”生成的密码哈希是:“$ 2y $ 10 $ W3bOAG0BP / DExr / qpiT0ueVS3YHb2NVeSC3.oMAaVQbHlodJVudK。”。

它仍然给我一个错误,密码不正确,我的猜测是比较时的密码不匹配,但我不确定为什么。

任何进一步的建议肯定会受到赞赏。

2 个答案:

答案 0 :(得分:1)

  

为“ password_28”生成的密码哈希为:“ $ 2y $ 10 $ W3bOAG0BP / DExr / qpiT0ueVS3YHb2NVeSC3.oMAaVQbHlodJVudK。”

Story checks out

  

它仍然给我一个密码不正确的错误,我的猜测是比较时的密码不匹配,但是我不确定为什么。

// ...
     $user = $result->fetch_assoc();
// ...
     if ( password_verify($_POST['password'], $user['password']) ) {
// ...

是否为$result返回了多行?您是否有可能在此位置比较了错误的哈希值?

要解决此问题,请将$_POST['password']硬编码为"password_28",然后查看它是否仍然失败。然后还原您的更改并对密码哈希进行硬编码。它仍然会失败吗?

如果第一次失败,则可能是在应用程序的其他地方更改了$_POST,这导致验证失败。

如果第二次失败,请首先检查您是否只返回了一行(否则,这是不重要的修复:确保为正确的用户使用正确的密码hah)。如果是这样,您可能会遇到密码存储方式存储方面的编码问题。数据库列对于密码哈希而言是否太短? (通常,对于MySQL,您通常希望使用varchar(255)TEXT,因为除非在严格模式下运行,否则MySQL默认会被截断。)

最后,我建议不要使用$mysqli->escape_string() ,而应该采用prepared statements。准备语句是much more robust strategy,用于防止PHP软件中的SQL注入而不是转义。

答案 1 :(得分:-1)

您不是在与哈希密码进行比较,而是在将原始帖子密码进行比较...

///在代码的第6行中,您对密码进行了哈希处理

$ password = $ mysqli-> escape_string(password_hash($ _ POST ['password'],PASSWORD_BCRYPT));

//在第16行上您不

if(password_verify($ _ POST ['password'],$ user ['password'])){

//所以请尝试一下...

if(password_verify($ password,$ user ['password'])){

相关问题