2014-09-23 55 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/