我现在正在使用CakePHP,如果我的用户忘记了密码我希望允许他们重置密码。 (即我用新的临时密码向他们发送邮件)。
但是有一个问题。存储在我的数据库中的密码由Auth组件进行哈希处理,这意味着如果我尝试从我的用户模型中选择所有密码,我将获得密码的哈希版本。更进一步,我不知道如何在生成一个新密码后保存密码HASHED。
我已经谷歌搜索了一段时间才找到答案,但似乎无法找到任何关于如何做到这一点的例子。
有没有人尝试类似的东西或知道我该怎么做?
答案 0 :(得分:1)
好的,2.x绝对可以提供更多控制权。我只是像我一样在我的User模型的beforeSave方法中哈希密码:
public function beforeSave() {
if (isset($this->data['User']['password'])) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
return true;
}
这允许您在Controller的密码重置操作中以纯文本形式创建密码,通过电子邮件发送给用户,然后在用户模型中设置密码并保留密码(密码在到达数据库之前进行哈希处理)。这里重要的是你的密码保持纯文本,直到你的控制器调用save方法。
通常我总是在控制器操作的密码字段中添加一个未设置,这将保存用户记录,以确保它不会被重新散列。第二个选项是向用户模型添加一个afterFind回调,每次加载用户模型时都会取消设置。
关于一次性重置键....我在User对象中有一个额外的字段,我在两种情况下使用。电子邮件验证和密码重置。创建用户时,将其设置为SHA1(+ +)。链接将通过电子邮件发送给用户,并将其发送到用户控制器的验证操作。验证该密钥后,该列将在数据库中清除。
与密码重置相同。当他们请求重置时,该值以相同的方式生成,并且用户控制器的重置操作的链接通过电子邮件发送给用户。他们输入他们的用户ID,如果链接中的密钥与他们的数据库行中的密钥匹配,他们可以更改他们的密码。更改密码后,将再次清除此值。
发送临时密码的最大问题是它会创建一个DoS机制(针对用户,而不是您的站点)。如果我决定骚扰某人,我可以创建一个每小时不断重置密码的任务。他们在检查他们的电子邮件之前无法进入,但之后它会再次发生变化。使用密钥,他们将收到一封带有重置链接的电子邮件,但他们当前的密码仍然有效,因为重置代码的存在不会阻止他们登录。
答案 1 :(得分:0)
我认为你无法将加密密码转换为解密。 因此,如果您想了解如何重置密码,请阅读cakephp的CakeDC插件。
这是cakephp的标准插件。
答案 2 :(得分:0)
试试这个
function admin_reset($token = null) {
/**
* if logged in, send to home/dashboard page
*/
if (count($this->Session->read("Auth.User"))) {
return $this->redirect('/');
}
$this->set('title_for_layout', 'Reset Password');
$this->layout = 'admin';
$this->User->recursive = -1;
if (!empty($token)) {
$u = $this->User->findBytokenhash($token);
if ($u) {
$this->User->id = $u['User']['id'];
if (!empty($this->data)) {
$this->User->data = $this->data;
$this->User->data['User']['username'] = $u['User']['username'];
$new_hash = sha1($u['User']['username'] . rand(0, 100)); //created token
$this->User->data['User']['tokenhash'] = $new_hash;
if ($this->User->save($this->User->data, false)) {
$this->Session->setFlash(__('Password has been updated.'), 'default', array('class' => 'alert alert-success'));
$this->redirect(array('controller' => 'users', 'action' => 'login'));
}
}
} else {
$this->Session->setFlash(__('Token corrupted. Reset link work only for once, please try again.'), 'default', array('class' => 'alert alert-success'));
}
} else {
//$this->redirect('/');
}
}