我想从同一用户的当前会话中注销记录在不同浏览器/环境中的用户会话。与此类似的功能 - https://www.facebook.com/settings?tab=security§ion=sessions&view。
Yii2 是使用的后端框架。使用 redis 进行会话管理 - yii2-redis 。我还保存了保存在数据库中的会话ID。
但没有取得任何成功。
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);
如果有人成功实施此功能,请分享您的解决方案。如果有任何关于此的文件可以提供帮助,请提供。
答案 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,
]);
}
}