密码在编辑时哈希两次 - CakePHP

时间:2013-02-01 08:19:52

标签: php authentication cakephp-2.0

我有一个用户编辑视图。当人们访问此视图时,密码块中包含哈希密码。

如果您单击“保存”,它(显然)会再次哈希密码,因为这是在我的用户模型中。

public function beforeSave($options = array()) {
    if(!empty($this->data['User']['password'])) {
        $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
    }
    return true;
}

但是我不希望它有两次哈希(因为这意味着密码已经改变)。我更改了编辑视图,并将array('value' => '','autocomplete'=>'off')添加到密码字段中。现在当我保存它时,它会在数据库中保存一个空白字符串。我认为这会阻止它使用if(!empty($this->data['User']['password']))函数中的beforeSave语句执行此操作。

如何防止密码被双重哈希?

5 个答案:

答案 0 :(得分:5)

解决方案非常简单。只需更改beforeSave中的if语句:

public function beforeSave($options = array()) {
    if(!empty($this->data['User']['password'])) {
        $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
    }
    return true;
}

为:

public function beforeSave($options = array()) {
    if(!empty($this->data['User']['password'])) {
        $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
    } else {
        unset($this->data['User']['password']);
    }
    return true;
}

答案 1 :(得分:3)

比较哈希:

您可以将数据库中保存的哈希值与密码字段中的文本进行比较。如果您没有触摸密码(更改了密码字段),则哈希应该匹配。假设您保存的哈希是xyz,并且密码哈希中加载的哈希仍未改动,xyz;在这种情况下,你不必重新做任何事情,哈希应该保持不变。

在另一种情况下,我们假设您保存的哈希为xyz,但您将密码html字段编辑为abc;在这种情况下,您必须重新扫描新密码(abc),然后替换数据库记录中的旧密码。

所有这些都可以在代码中翻译如下:

public function beforeSave($options = array()) {

    if (isset($this->data[$this->alias]['password'])) {

        if(isset($this->data[$this->alias]['id'])) {
            $id = $this->data[$this->alias]['id'];
            $user = $this->findById($id);
        } else {
            $id = false;
        }

        if(!$id || $this->data[$this->alias]['password'] != $user['User']['password']) {
            $passwordHasher = new SimplePasswordHasher();
            $this->data[$this->alias]['password'] = $passwordHasher->hash(
                $this->data[$this->alias]['password']
            );
        }

    }

    return true;
}

此致 中号

答案 2 :(得分:1)

在视图中使用备用字段名称(例如$this->Form->password('pwd')

public function beforeSave($options = array()) {
    if (!empty($this->data[$this->alias]['pwd'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['pwd']);
 }
    return true;
}

这可以防止密码被覆盖/空白。 信用,解释和其他最佳做法at this link.

答案 3 :(得分:0)

通常,用户编辑页面与您描述的不同。如果存储散列密码,则密码永远不会在编辑视图中返回。

如果用户想要更改密码,表单通常包含3个字段

  • 旧密码
  • 新密码
  • 新密码(检查它是否与前一个密码相同)

接下来会发生什么:

  • 检查两个新密码是否具有相等的值
  • 哈希旧密码
  • 哈希新密码
  • 检查旧密码哈希是否等于数据库中的哈希...如果是,则旧哈希将被新哈希替换

在您的示例中,您无法区分散列和常规密码,因此您的代码可能永远不会在其当前状态下工作,因为散列也只是字符串文字。

答案 4 :(得分:0)

public function beforeSave($options = array()) {
    if(AuthComponent::user('id') == null)
        if (isset($this->data[$this->alias]['password'])) {
            $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
        }
        return true;
}