【问题标题】:Problem with password_verify when create users with CodeIgniter使用 CodeIgniter 创建用户时出现密码验证问题
【发布时间】:2018-12-04 21:22:35
【问题描述】:

我的问题是我正在使用 CodeIgniter。我创建了一个管理员面板,用于创建用户和密码。我在将它们发送到数据库之前使用 password_hash(事实上,在数据库中我可以看到散列密码)。 问题是......当我尝试登录时,它没有。我只能使用管理员帐户访问,这是我在开始使用 CodeIgniter 之前创建的。 我可以使用管理员帐户登录,但不能使用使用管理面板创建的帐户登录。 我尝试使用一个非常简单的 php 文件(在 CI 之外)将哈希复制并粘贴到我的数据库中的一个用户字段中,并且它起作用了。我不明白为什么这在 CodeIgniter 中不起作用。 这是我的代码的一部分:

public function insert_user($username, $passw, $perm){

  $hashed_pass = password_hash($passw, PASSWORD_DEFAULT);

  $data = array(
    "username" => $username,
    "passw" => $hashed_pass,
    "perms" => $perm
  );

  $this->db->insert('usuarios', $datos);

}

上面的函数在数据库中正确插入数据。我可以看到密码散列,但是当我尝试从管理面板使用创建的用户登录时,它不起作用(但它使用管理员帐户,并且他们都使用相同的功能登录)。

public function login($username, $password){

  $query = $this->db->query("select passw, perms from users where username = '".$username."'");

  $result = $query->row();
  $p_hashed = $result->passw;
  $perms= $result->perms;


  if(password_verify($password, $p_hashed)){
    $info= array(
      "is_valid" => true,
      "username" => $username,
      "perms" => $perms
    );
    return $info;
  }
  else {
    $info= array(
      "is_valid" => false,
      "username" => ""
    );
    return $info;
  }
}

我检查了数据库和 CI 字符集,都是 utf8。我不明白为什么不起作用...我将不胜感激。

P.S.:如果变量的名称不相关或不相同是因为我将它翻译成英文(我不是以英语为母语的人,所以我在这个项目中没有使用英文)。

谢谢。

编辑

我已将代码更改为使用 md5 而不是 password_hash,但我遇到了同样的问题。

编辑 2

我检测到问题:我正在比较 2 个密码(第一个密码和确认密码)。在那次审查之后,我将数据传递给模型......但是我发送给模型的密码变量是一个没有数据的新变量。我正在散列一个未初始化的变量。

【问题讨论】:

  • 你的 SQL 中有一个 SQL 注入,所以弄清楚它为什么不验证可能是你最后关心的问题,但是你是否尝试过调试 $password 以查看它包含的内容,它应该是明文
  • 你确定表的passw列适合password_hash()的输出吗?即它是否能够在不截断输入的情况下处理所有数据?它是正确的数据类型吗?
  • ^ 最可能的情况
  • 是的,是 varchar(255)。不可能。
  • 好的,我解决了。查看答案中的 EDIT 2 以获取更多信息。

标签: php codeigniter php-password-hash


【解决方案1】:

您显示的代码似乎没有任何问题。正如我评论的那样,可能的问题是表中的passw 列正在截断要插入的数据。

检查documentation for password_hash 以查找各种算法的返回数据大小,并相应地调整表结构。对于PASSWORD_DEFAULT,建议大小为 255 个字符。

下面的代码不是答案,但我有时间并认为您可能会发现 login() 的重构版本很有趣。

假设您已正确验证和清理传递给login() 方法的值。

public function login($username, $password)
{
    //use query binding so values are automatically escaped, producing a safer query
    $query = $this->db->query("select username, perms, passw 
                               from users where username = ?", [$username]);
    // make sure query worked and found a record
    if($query && $query->num_rows() > 0)
    {
        // get an row array so you don't need to make an array
        $row = $query->row_array();
        if(password_verify($password, $row['passw']))
        {
            unset($row['passw']); // remove passw from array
            $row['is_valid'] = true;
            return $row;
        }
    }

    return array( "is_valid" => false,  "username" => "");
}

【讨论】:

  • 我检查了数据库,密码字段是 varchar (255)。我使用了您编写的代码(感谢绑定,对此一无所知),没有任何改变。只有管​​理员可以登录。
  • 不知道该告诉你什么。我测试了代码,它运行良好。您对更改数据库后注册的用户进行了测试?
  • 今天又过了 45 分钟,逐行查看代码,我发现了问题:我正在比较 2 个密码(第一个和确认密码)。在那之后,我将数据传递给模型......但是我发送给模型的密码变量是一个没有数据的新变量。我正在散列一个未初始化的变量。非常感谢您的参与。对于这个问题,我很抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多