yii2 session用户自定义信息丢失问题待解

Posted sjg20010414

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yii2 session用户自定义信息丢失问题待解相关的知识,希望对你有一定的参考价值。

问题:yii2登录部分中,登录后session记录了一些变量,但实际运行中,有时候这些session变量会消失(用户登录身份仍然保持)

代码类似如下:

    public function actionLogin()
    {
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            Yii::$app->session->setFlash('success', "{$model->username} 登录成功!");
            $user = Yii::$app->user->identity;
            Yii::$app->session->set('user_id', $user->id);
            Yii::$app->session->set('access_token', $user->access_token); 
            // 这里省略一些代码
            Yii::$app->session->set('dept_id', $dept->id);
            Yii::$app->session->set('dept_name', $dept->name); 
            return $this->goBack();
        } else {
            $model->password = '';
            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

问题通常出现在比较长时间没有操作,然后刷新网页的时候。通过观察后台session文件可以知道,当session变量消失的时候,后台session文件的确变掉了(不仅文件名变了,内部数据也变了),换句话说,session id已经变了。

session id 变是正常的,因为 yii2 的 session 组件里面本身就有下面的代码

    /**
     * Starts the session.
     */
    public function open()
    {
        if ($this->getIsActive()) {
            return;
        }

        $this->registerSessionHandler();

        $this->setCookieParamsInternal();

        YII_DEBUG ? session_start() : @session_start();

        if ($this->getUseStrictMode() && $this->_forceRegenerateId) {
            $this->regenerateID();
            $this->_forceRegenerateId = null;
        }

        if ($this->getIsActive()) {
            Yii::info('Session started', __METHOD__);
            $this->updateFlashCounters();
        } else {
            $error = error_get_last();
            $message = isset($error['message']) ? $error['message'] : 'Failed to start session.';
            Yii::error($message, __METHOD__);
        }
    }

$this->regenerateID(); 这里相关代码为 (实际 regenerateID()不止这一个地方调用了)

    public function regenerateID($deleteOldSession = false)
    {
        if ($this->getIsActive()) {
            // add @ to inhibit possible warning due to race condition
            // https://github.com/yiisoft/yii2/pull/1812
            if (YII_DEBUG && !headers_sent()) {
                session_regenerate_id($deleteOldSession);
            } else {
                @session_regenerate_id($deleteOldSession);
            }
        }
    }

这是一种安全机制,session id在会话过程中会不断变化,对于session安全,可以参考:

现在的问题主要是,为什么 session id变化了,session 的一部分数据“继承”过来了(主要是 identity 信息__flash__id__authKey),而我们的代码设置的信息有时候没有“继承”过来?

root@zime-virtual-machine:/var/lib/php/sessions# cat sess_rg97b7igbdvos3itc9clum0nd2 
__flash|a:0:{}__id|i:38;__authKey|N;

以上是关于yii2 session用户自定义信息丢失问题待解的主要内容,如果未能解决你的问题,请参考以下文章

Cookie 和 Session

yii2实战之用户注册登录

监听器实现案例----自定义session扫描器和统计在线用户人数及用户信息

yii2 配置文件加载顺序, 以及调用自定义配置信息。

python tornado 自定义session

session放数据库里解决丢失的问题