我正在使用YII框架处理'忘记密码'功能。流程是这样的 - >
在登录页面上,提供了链接'忘记密码'。单击它时,将呈现一个新视图,用户需要在其中放置其电子邮件地址。邮件将被发送到邮件ID,并且在该邮件中提供了一个链接,用户将点击该链接以“重置密码”PAge,他可以在其中设置新密码。
我正在与Sessions合作以实现此方案。问题是会话被覆盖,只有最新输入的EMAIL地址(用户)可以重置密码(当通过逐个输入多个EMAIL ID尝试时)。
1)首先,我在点击“提交按钮”后启动了会话。随机字符串保留在会话中并发送给EMAIL。当用户单击重置链接时,将打开RESET页面,如果字符串与会话字符串匹配,则可以重置密码。
如果只使用一个EMAil,所有这些工作都很好。如果我输入两个电子邮件ID ..我收到两个邮件生成重置链接,,,但当我点击第一个邮件ID的重置链接,,,我得到错误消息,当我点击收到重置链接在第二个邮件地址,然后它的工作原理。
public function actionForgotPassword()
{
$model = new ForgotPasswordForm;
$userModel = new UserDetails;
if(isset($_POST['ForgotPasswordForm']))
{
$model->attributes = $_POST['ForgotPasswordForm'];
// validate user input and redirect to the previous page if valid
if($model->validate())
{
$getMail = $_POST['ForgotPasswordForm']['email'];
$user = UserDetails::model()->findByAttributes(array(
'email' => $getMail
));
if($user)
{
session_start();
$sessionString = $model-> genRandomSaltString();
Yii::app()->session['identityString'] = $sessionString;
///Below is the MAIL function
}
}}}
RESET PAge上的代码是
public function actionNewPassword()
{
session_start();
$model = new ChangePasswordForm;
$userModel = new UserDetails;
$email = Yii::app()->request->getParam('tag');
$getSessionKey = Yii::app()->request->getParam('key');
//print_r($_SESSION);die;
$catchSessionValue = Yii::app()->session['identityString'];
if(!empty($_SESSION) && !empty($catchSessionValue))
{
if($catchSessionValue == $getSessionKey && $email !== null)
{
$user_arr = UserDetails::model()->findByAttributes(array('email' => $email));
$user_name = $user_arr['username'];
$user_id = $user_arr['id'];
Yii::app()->user->setFlash('info', "Enter your New Password here.");
if(isset($_POST['ChangePasswordForm']))
{
$this->render('changepassword',array('change_pw_form'=>$model,'user'=>$user_arr));
}
else{
$this->render('changepassword',array('change_pw_form'=>$model,'user'=>$user_arr));
}
}
else
{
Yii::app()->user->setFlash('error', "Something went Wrong. Try Again!");
$this->render('changepassword');
//$this->redirect(Yii::app()->createUrl('site/login'));
}
}
else
{
$user_arr = UserDetails::model()->findByAttributes(array('email' => $email));
Yii::app()->user->setFlash('error', "Sorry ! The link has been expired. Please try again.");
$this->render('changepassword',array('change_pw_form'=>$model,'user'=>$user_arr));
// $this->redirect(Yii::app()->createUrl('site/login'));
}
}
答案 0 :(得分:0)
您反复覆盖该值,因此只存储了最后一封电子邮件'identityString'
。
<强>为什么吗
对于相同的浏览器会话&#39; (意味着您没有关闭浏览器或在其他浏览器中打开页面),会话保持不变。 (除非在你的php代码中明确销毁)
只要会话保持不变,您每次都有效地覆盖'identityString'
会话值。意思是,发送第一封邮件时生成的随机字符串被发送第二封邮件时生成的随机字符串覆盖。这就是为什么你没有在第二个错误中得到错误。
在这种情况下,会话无用,因为一旦用户关闭浏览器或使用其他浏览器或设备点击邮件中的链接,就无法访问您存储的值。
您可以将此类信息存储在数据库或缓存中。如果您不想使用数据库,Yii中提供了文件缓存。使用Yii::app()->cache->set($id, $value);
其中$id
可以是根据用户的电子邮件地址生成的唯一字符串,而$value
是$sessionString
示例:强>
$id = 'identityString.'.md5($getEmail);
// 'identityString.9e107d9d372bb6826bd81d3542a419d6'
Yii::app()->cache->set($id, $sessionString);
您将再次检索此内容:
$id = 'identityString.'.md5($email);
$catchSessionValue = Yii::app()->cache->get($id);
以下是会话工作原理的简单说明:
每当在您的服务器上初始化会话时,浏览器都会存储具有唯一值的会话cookie。从那时起,每个请求都会传递此cookie。唯一值用于标识会话,服务器检索为该会话初始化的所有变量。 浏览器在关闭时会丢失会话cookie,因此会丢失对该会话的访问权限。
另外,一个stackoverflow用户写了这个,通过它: http://machinesaredigging.com/2013/10/29/how-does-a-web-session-work/