【问题标题】:Yii2 remote logout a user session from the user current sessionYii2 从用户当前会话远程注销用户会话
【发布时间】:2015-11-04 01:16:29
【问题描述】:

我想注销在与同一用户的当前会话不同的浏览器/环境中登录的用户会话。与此类似的功能 - 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中的key并没有注销。

将会话 id 更改为旧的,然后销毁会话也不起作用。

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

如果有人成功实现了这一点,请分享您的解决方案。另外,如果有任何相关的文档可以提供帮助,请提供。

【问题讨论】:

  • 感谢@Ngô Văn Thao 和@Nate 的回答。这是我从他们的答案中获取输入的方法。将 enableAutoLogin 设置为 false。创建一个session table(user_id, session_id) 以及与设备、浏览器相关的其他属性。在afterLogin 方法中,将user_id和session_id添加到session表中。要远程注销会话,请使用 -Yii::$app->session->destroySession(sessionId) 销毁会话并更改用户的 auth_key。注意:这不适用于默认的 Session 组件。与yii\redis\Session 一起工作正常

标签: php session redis yii2 logout


【解决方案1】:

第一个,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,该会话将立即注销。 我一直在为我的项目使用这个解决方案,并且效果很好。

【讨论】:

  • 不适合我。我已将 autoLogin 设置为 true。我使用类似于github.com/yiisoft/yii2-app-basic/blob/master/models/… 的基于用户名+密码的登录。更改 auth_key 只会更新 _identity cookie 而不会注销会话。您能否分享一些您的实现示例代码。还有您使用哪种登录方式。
  • 你必须像你一样杀死 AuthKey 和 PHP 会话
  • 更改或删除AuthKey 只是阻止自动登录,kill php session 将立即杀死用户会话。
  • 我确实删除了 auth_key 并销毁了会话。但是远程用户会话没有注销。
  • 尝试禁用自动登录。删除会话后您的用户是否注销?
【解决方案2】:

根据 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,
        ]);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2019-07-09
    • 2012-05-11
    • 2019-10-11
    相关资源
    最近更新 更多