Yii2远程注销用户当前会话中的用户会话

时间:2015-08-11 17:21:12

标签: php session redis yii2 logout

我想从同一用户的当前会话中注销记录在不同浏览器/环境中的用户会话。与此类似的功能 - https://www.facebook.com/settings?tab=security&section=sessions&view

Yii2 是使用的后端框架。使用 redis 进行会话管理 - yii2-redis 。我还保存了保存在数据库中的会话ID。

我跟着这篇文章 - http://www.codeinphp.com/general/php-code-snippets/remotely-destroy-different-session-php-forced-user-signout/

但没有取得任何成功。

session_id($old_session_id);
session_start(); // This line throws error.
session_destroy();

使用\Yii::$app->session->destroySession($oldSessionId)删除redis中的密钥没有注销。

将会话ID更改为旧会话ID然后销毁会话也无法正常工作。

$currentSessionId = \Yii::$app->session->getId();
\Yii::$app->session->setId($oldSessionId);
\Yii::$app->getSession()->destroy();
\Yii::$app->session->setId($currentSessionId);

如果有人成功实施此功能,请分享您的解决方案。如果有任何关于此的文件可以提供帮助,请提供。

2 个答案:

答案 0 :(得分:4)

第一个session_start()必须在session_id()之前调用,只需调用一次

if (session_status() == PHP_SESSION_NONE) {
   session_start();
}
session_id($old_session_id);
session_destroy();

但是只删除会话,如果您允许用户自动登录,这是不够的,因为浏览器将使用cookie自动登录。要解决此问题,您必须更改用户AuthKey - Yii2使用AuthKey来验证用户自动登录。默认情况下,每个用户在用户表中只有一个AuthKey,以便在任何地方更改AuthKey用户注销时。所以我们必须定制。为每个用户会话创建AuthKey,存储在不在用户表中的某个位置。操作简单:扩展yii \ web \ User类覆盖afterLogin函数,为每个登录会话创建AuthKey。覆盖validateAuthKey函数以验证自动登录使用我们的自定义AuthKey。现在,当您想杀死任何用户会话时:终止会话将立即注销的PHP会话ID和AuthKey。 我一直在为我的项目使用这个解决方案,它工作正常。

答案 1 :(得分:1)

根据Ngo的回答,我找到了一种效果很好且设置更容易的方法。

1)在用户表中添加“last_session_id”字段。

2)将以下内容添加到主控制器:

public function afterAction($action, $result)
{
    $result = parent::afterAction($action, $result);

    if(Yii::$app->user->id)
    {
        //update the user table with last_session_id
        $user = User::find()->where(['id' => Yii::$app->user->id])->one();
        $user->last_session_id = Yii::$app->session->id;
        $user->save(false);
    }

    return $result;
}

3)将站点/登录操作更改为以下内容:

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

    $model = new LoginForm();
    if ($model->load(Yii::$app->request->post()) && $model->login()) {

        //delete previous session ID and change auth key
        Yii::$app->session->destroySession(Yii::$app->user->identity->last_session_id);
        $u = \common\models\User::find()->where(['id' => Yii::$app->user->id])->one();
        $u->auth_key = Yii::$app->security->generateRandomString();
        $u->save(false);
        return $this->goBack();
    } else {
        return $this->render('/site/login', [
            'model' => $model,
        ]);
    }
}