注册时密码错误但使用 bcrypt 更改密码时有效

Wrong password when register but working when change it whit bcrypt

我在我的系统上发现了一些关于用户注册和密码的问题。当我创建新用户时,我通过 bcrypt 散列了他的密码。一切都保存在数据库中,但最近我发现我无法登录新创建的用户。我猜密码有问题。

奇怪,但是当我和这个用户一起使用忘记密码并添加新密码时,我能够登录。用户注册和忘记密码都使用相同的哈希系统。这是注册过程以及密码的保存方式:

这个->注册后无法登录

// included db connection, password hash file etc..

//hash the password
$hashedpassword = $user->password_hash($_POST['user_password'], PASSWORD_BCRYPT);   

  if(!isset($error)){

        try {

           $stmt = $pdo->prepare('INSERT INTO users (user_username, user_password, user_email) VALUES (:user_username, :hashedpassword, :user_email)');

           $stmt->execute(array(
              ':user_username' => $_POST['user_username'],
              ':hashedpassword' => $hashedpassword,
              ':user_email' => $_POST['user_email']
           ));

        } catch(PDOException $e) {
              var_dump ($e->getMessage());
              exit;
        }
  }
     // html part
  <div class="form-group">
      <label class="control-label col-sm-2" for="password">Password:</label>    private function get_user_hash($username){  

    try {
        $stmt = $this->_db->prepare("SELECT user_password FROM users WHERE user_username = :username AND active='Yes'");
        $stmt->execute(array('username' => $username));

        $row = $stmt->fetch();
        return $row['user_password'];

    } catch(PDOException $e) {
        echo '<p class="bg-danger">'.$e->getMessage().'</p>';
    }
}

public function login($username,$password){

    $hashed = $this->get_user_hash($username);

    if($this->password_verify($password,$hashed) == 1){

        $_SESSION['loggedin'] = true;          
        return true;
    }   
}
      <div class="col-sm-10"> 
         <input type="password" class="form-control" name="user_password" id="user_password" placeholder="Enter password">
      </div>
 </div>

密码重置。 这个->修改密码后可以登录

 if(!isset($error)){

    //hash the password
    $hashedpassword = $user->password_hash($_POST['user_password'], PASSWORD_BCRYPT);

    try {

         $stmt = $pdo->prepare("UPDATE users SET user_password = :hashedpassword, resetComplete = 'Yes', active='Yes' WHERE resetToken = :token");
         $stmt->execute(array(
            ':hashedpassword' => $hashedpassword,
            ':token' => $row['resetToken']
        ));

        //redirect to index page
        header('Location: index.php?action=resetAccount');
        exit;

    //else catch the exception and show the error.
    } catch(PDOException $e) {
        $error[] = $e->getMessage();
    }

}
<div class="input-group input-group-lg">
     <span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span>
         <input type="password" class="form-control" name="user_password" id="user_password" placeholder="Enter your new password"/>
</div>
<div class="input-group input-group-lg">
     <span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span>

      <input type="password" class="form-control" name="passwordConfirm" id="passwordConfirm" placeholder="Re-enter your new password" />
</div> 

我看不出有什么不同。他们都使用相同的数据库连接、相同的数据库 table、相同的密码哈希文件。我不知道该怎么办。

更新:密码的数据库字段是 VARCHAR(120) 所以它有足够的 space 用于散列。此外,我确定在 1-2 周之前一切正常,因为我已经创建了一些帐户..我没有更改任何内容,现在我无法登录..

更新 2: user.php ..

include('password.php');
$pdo = Database::connect();
class User extends Password{

private $_db;

function __construct($pdo){
    parent::__construct();

    $this->_db = $pdo;
}
private function get_user_hash($username){  

    try {
        $stmt = $this->_db->prepare("SELECT user_password FROM users WHERE user_username = :username AND active='Yes'");
        $stmt->execute(array('username' => $username));

        $row = $stmt->fetch();
        return $row['user_password'];

    } catch(PDOException $e) {
        echo '<p class="bg-danger">'.$e->getMessage().'</p>';
    }
}

public function login($username,$password){

    $hashed = $this->get_user_hash($username);

    if($this->password_verify($password,$hashed) == 1){

        $_SESSION['loggedin'] = true;          
        return true;
    }   
}

index.php登录表单在哪里

//html part
<div class="input-group input-group-lg">
     <span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span>

     <input type="password" class="form-control" name="password" id="password" placeholder="password" />
</div>

// php part
// include database, user.php
if(isset($_POST['submit'])){

$username = $_POST['username'];
$password = $_POST['password'];

if($user->login($username,$password)){ 

           $id=$user->login_user_id($username);// get user id
           $permissions=$user->login_user_permissions($username);// get user role


       $_SESSION['user_id'] = $id;// assing user_id to session
       $_SESSION['user_username'] = $username;
       $_SESSION['user_role'] = $permissions;
    header('Location: admin/index.php');
    exit;

} else {
    header('Location: index.php');
    echo '';

}
}   

在您的注册表中,您可以这样做:

$stmt = $pdo->prepare('INSERT INTO users (user_username, user_password, user_email) VALUES (:user_username, :hashedpassword, :user_email)');

在此之后,在您验证两个密码的登录表单中,我注意到您检查了 select 并检查了字段 active.. AND active='Yes'...

$stmt = $this->_db->prepare("SELECT user_password FROM users WHERE user_username = :username AND active='Yes'");

在密码更改部分,您更新了同一字段 active='Yes'...

$stmt = $pdo->prepare("UPDATE users SET user_password = :hashedpassword, resetComplete = 'Yes', active='Yes' WHERE resetToken = :token");

因此,如果您在数据库中设置或没有设置此列,请检查注册表。或者你输入一些默认值?