Php 当多个用户访问YII时,会话值将被覆盖

Php 当多个用户访问YII时,会话值将被覆盖,php,email,session,yii,forgot-password,Php,Email,Session,Yii,Forgot Password,我正在使用YII框架开发“忘记密码”功能。流程是这样的-> 在登录页面上,提供了一个链接“忘记密码”。单击它,将呈现一个新视图,用户需要在其中放置其电子邮件地址。一封邮件被发送到邮件ID,并在该邮件中提供了一个链接,点击该链接,用户将进入“重置密码”页面,在该页面上他可以设置新密码 我正在使用会话来实现此场景。问题是会话正在被覆盖,只有最新输入的电子邮件地址用户才能通过逐个输入多个电子邮件ID来重置密码 1首先,我已在单击“提交按钮”后启动会话。会话中会保留一个随机字符串并发送到电子邮件。当用户

我正在使用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
                }
}}}
重置页面上的代码为

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”会话值。也就是说,发送第一封邮件时生成的随机字符串被发送第二封邮件时生成的随机字符串覆盖。这就是为什么第二个错误没有出现

在这种情况下,会话没有用处,因为一旦用户关闭浏览器或使用其他浏览器或设备单击邮件中的链接,就无法访问存储的值

您可以将此类信息存储在数据库或缓存中。如果您不想使用db,Yii中提供文件缓存。使用Yii::app->cache->set$id$value;其中,$id可以是从用户的电子邮件地址生成的唯一字符串,$value是$sessionString

例如:

您将再次检索此文件:

$id = 'identityString.'.md5($email);
$catchSessionValue = Yii::app()->cache->get($id);
下面是会话工作原理的简单解释:

无论何时在服务器上初始化会话,浏览器都会存储具有唯一值的会话cookie。从那时起,每个请求都会将此cookie传递给服务器。唯一值用于标识会话,服务器检索为该会话初始化的所有变量。 浏览器在关闭会话cookie时将丢失该会话cookie,因此对该会话的访问将丢失

另外,一位stackoverflow用户写了这样一句话,请仔细阅读:

您可以保留密码重置随机字符串,最好在数据库中为该电子邮件使用时间戳,而不是将其保留在会话中,因为会话对于该电子邮件是唯一的,因此每封电子邮件都有唯一的重置字符串。
$id = 'identityString.'.md5($email);
$catchSessionValue = Yii::app()->cache->get($id);