目前正在处理我负责的CakePHP应用程序的密码重置脚本。
到目前为止,我有一个忘记的脚本,我创建了一个随机字符串,将其添加到相关用户并通过电子邮件向用户发送重置链接。 (域名实际上是直播域名)
Click on the link below to Reset Your Password
Click here to Reset Your Password
or Visit this Link
domainnamehere/users/reset/e9bb0ab37ff9175a856f0aff3e18db801451306e5a50bfc618c43280b62628e4bdb8131b638e042b47d42ca1516de11f1b025d646406bfd31054db167d5ef430#62442a331b1f9a3e37cbb9a33c1d619b8a8e0a18
This email was sent using the CakePHP Framework
点击重置并加载重置表单后,它似乎正在跳过我最后一个没有令牌值的else语句?
function reset($token=null){
//$this->layout="Login";
$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->validates(array('fieldList'=>array('password','password_retype')))){
if($this->User->save($this->User->data))
{
$this->Session->setFlash('Password Has been Updated');
$this->redirect(array('controller'=>'users','action'=>'login'));
}
else
{
$this->Session->setFlash('Error updating values');
}
}
else{
$this->set('errors',$this->User->invalidFields());
}
}
}
else
{
$this->Session->setFlash('Token Corrupted,,Please Retry.the reset link work only for once.');
}
}
else{
// $this->redirect('/');
$this->Session->setFlash($token);
}
}
reset.ctp
<div class="users form">
<?php echo $this->Form->create('User', array('action' => 'reset')); ?>
<fieldset>
<legend><?php echo __('Change your Password'); ?></legend>
<?php
//debug($users);
echo $this->Form->input('password', array('label' => 'Change password'));
echo $this->Form->input('password_retype', array('label' => 'Confirm password', 'type' => 'password'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
对于这种情况的任何帮助都会非常感激,因为我被卡住了,谢谢!
答案 0 :(得分:2)
嗯,......当你提交时,你没有发回令牌......
你做
<?php echo $this->Form->create('User', array('action' => 'reset')); ?>
并将表单提交到users/reset
,而不是users/reset/token
。因此,要么将令牌与动作提交一起传递,就像这样
<?php echo $this->Form->create('User', array('action' => 'reset', $token)); ?>
或将其与表单一起提交为隐藏输入
<?php
//debug($users);
echo $this->Form->input('password', array('label' => 'Change password'));
echo $this->Form->input('password_retype', array('label' => 'Confirm password', 'type' => 'password'));
//here
echo $this->Form->input('token', array('type'=>'hidden', 'value'=>$token)
?>
并在控制器中获取
if (!empty($token) && !empty($this->request->data['User']['token'])) {
将来,不要期望表单提交您通过url传递的所有值,这不是事情的运作方式:(
安全提示
如果我是邪恶的,或者如果Voldemort知道互联网,他可以尝试使用随机令牌调用您的重置URL来将密码更改为voldi-rocks
,然后尝试访问该网站。我建议有一个有效的重置令牌时间,如果一小时内未使用重置链接(例如),则使其无效。
当天提示
您可以将public $recursive = -1;
放在用户模型上,以避免将其放在控制器中的每个操作上。
答案 1 :(得分:0)
我们发现你必须在reset.ctp中登记注册表单中显示的其他必填字段,当然是隐藏的,一切都很完美,包括更新密码字段。
答案 2 :(得分:0)
function admin_forgotpwd() {
if (count($this->Session->read("Auth.User"))) {
return $this->redirect('/');
}
$this->set('title_for_layout', 'Forgot Password');
$this->layout = 'admin_login';
$this->User->recursive = -1;
if (!empty($this->data)) {
if (empty($this->data['User']['email'])) {
$this->Session->setFlash(__('Please enter your email.'), 'default', array('class' => 'alert alert-success'));
} else {
$email = $this->data['User']['email'];
$fu = $this->User->find('first', array('conditions' => array('User.email' => $email)));
if ($fu) {
//debug($fu);
if ($fu['User']['user_status'] == 'active') {
$key = Security::hash(String::uuid(), 'sha512', true);
$hash = sha1($fu['User']['username'] . rand(0, 100));
$url = Router::url(array('controller' => 'users', 'action' => 'reset'), true) . '/' . $key . '#' . $hash;
$ms = $url;
$ms = wordwrap($ms, 1000);
debug($url);
$fu['User']['tokenhash'] = $key;
$this->User->id = $fu['User']['id'];
if ($this->User->saveField('tokenhash', $fu['User']['tokenhash'])) {
$this->Session->setFlash(__('Check your email to reset password.', true), 'default', array('class' => 'alert alert-success'));
$this->redirect(array('controller' => 'users', 'action' => 'login'));
//============EndEmail=============//
} else {
$this->Session->setFlash(__("Error while generating reset link."), 'default', array('class' => 'alert alert-danger'));
}
} else {
$this->Session->setFlash(__('This account is not active yet.'), 'default', array('class' => 'alert alert-danger'));
}
} else {
$this->Session->setFlash(__('Email does not exist'), 'default', array('class' => 'alert alert-danger'));
}
}
}
}