我正在使用YII框架开发"忘记密码"功能。流程如下-->
在登录页面,会提供一个链接"忘记密码"。单击后,将呈现一个新视图,用户需要将其电子邮件地址放在其中。邮件被发送到邮件ID,邮件中提供了一个链接,点击该链接,用户将被带到"重置密码"页面,在那里他可以设置新密码。
我正在与塞申斯合作,以实现这一场景。问题是会话被覆盖,只有最近输入的电子邮件地址(用户)才能重置密码(当尝试一个接一个地输入多个电子邮件ID时)。
1) 首先,我在点击"提交按钮"后开始了会话。一个随机字符串保存在会话中并发送到电子邮件。当用户点击重置链接时,会打开重置页面,如果字符串与会话字符串匹配,则可以重置密码。
如果只使用一个电子邮件,所有这些都可以正常工作。如果我输入两个电子邮件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'));
}
}
您一次又一次地重写该值,因此只存储最后一封电子邮件的'identityString'
。
为什么
对于相同的"浏览器会话"(意味着您没有关闭浏览器或在其他浏览器中打开页面),会话保持不变。(除非在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/