2014-09-23 123 views
0

我正在使用YII框架开展'忘记密码'功能。流程是这样的 - >当多个用户访问YII时,会话值被覆盖

在登录页面,提供了一个链接'忘记密码'。点击它时,会呈现一个新视图,用户需要放置其电子邮件地址。一封邮件被发送到邮件ID,并在该邮件中提供一个链接,点击该链接后,用户将被带到'RESET密码'栏位,在那里他可以设置一个新密码。

我正在与Sessions合作完成此场景。问题是会话正在被覆盖,只有最近输入的EMAIL地址(用户)才能重置密码(当通过输入多个EMAIL ID之后再次输入)。

1)首先我点击'提交按钮'后开始会话。随机字符串保存在会话中并发送到EMAIL。当用户点击重置链接时,打开RESET页面,如果字符串与会话字符串匹配,则可以重置密码。

所有这些工作正常,如果只与一个EMAIL工作。如果我输入两个电子邮件ID的..我得到的邮件都与重置链接生成,,,,但当我点击重置链接的第一个邮件ID ,,,我得到错误消息,当我点击重置链接收到在第二个MAIL地址,然后它的工作。

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页面

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

您可以将您的密码重置随机字符串在数据库中(最好使用时间戳),该电子邮件,而不是将它保持在会议,这将对于该电子邮件是唯一的,这样每个电子邮件将具有唯一的重置字符串。 – Pramod 2014-09-23 11:02:07

回答

0

你一遍又一遍地重写值再次因此只被存储的最后一封电子邮件的'identityString'

为什么?

对于相同的'浏览器会话'(意思是你没有关闭浏览器或在不同浏览器中打开页面),会话保持不变。 (除非在您的php代码中明确销毁)

只要会话保持不变,您每次都有效地重写'identityString'会话值。意思是,发送第一封邮件时生成的随机字符串被发送第二封邮件时生成的随机字符串覆盖。这就是为什么你没有得到第二个错误。

在这种情况下,会话不起作用,因为一旦用户关闭浏览器或使用不同的浏览器或设备单击邮件中的链接,您存储的值就无法访问。

您可以将这些信息存储在数据库或缓存中。如果您不想使用db,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,因此对该会话的访问会丢失。

此外,一位同行的计算器用户写到这,通过它去: http://machinesaredigging.com/2013/10/29/how-does-a-web-session-work/