我有一个用户编辑视图。当人们访问此视图时,密码块中包含哈希密码。
如果您单击“保存”,它(显然)会再次哈希密码,因为这是在我的用户模型中。
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
语句执行此操作。
如何防止密码被双重哈希?
答案 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;
}