You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Yii 1.1.29中通过会话属性查找并销毁指定会话?

Yii 1.1.29 实现通过Access Token查找并销毁会话(SSO登出同步)

核心思路

Yii 1.1的会话存储分为数据库存储(推荐生产环境)和文件存储(默认方式)两种,针对这两种场景分别实现通过access token查找会话和销毁会话的逻辑即可完成SSO登出同步。


方案一:数据库存储会话(高效可靠)

如果站点已配置数据库存储会话,操作更直接:

1. 确认会话表结构

Yii默认的会话表结构可通过迁移生成,格式如下:

CREATE TABLE `session` (
    `id` CHAR(32) NOT NULL PRIMARY KEY,
    `expire` INTEGER,
    `data` TEXT
) ENGINE=InnoDB;

2. 查找对应会话

解析序列化的会话数据,筛选出包含目标access token的会话ID:

$targetToken = 'abcd'; // IDP传来的待销毁token
$matchedSessionIds = [];

// 查询所有未过期的会话
$activeSessions = Yii::app()->db->createCommand()
    ->select('id, data')
    ->from('session')
    ->where('expire > :currentTime', [':currentTime' => time()])
    ->queryAll();

foreach ($activeSessions as $session) {
    // 反序列化会话存储的属性数据
    $sessionAttributes = unserialize($session['data']);
    // 假设access token存储在会话的'access_token'字段下,根据实际业务调整
    if (isset($sessionAttributes['access_token']) && $sessionAttributes['access_token'] === $targetToken) {
        $matchedSessionIds[] = $session['id'];
        break; // 单个token对应单个会话时,找到即可终止遍历
    }
}

3. 销毁会话

遍历找到的会话ID,删除会话记录并清理关联缓存:

foreach ($matchedSessionIds as $sessionId) {
    // 删除数据库中的会话记录
    Yii::app()->db->createCommand()
        ->delete('session', 'id = :sid', [':sid' => $sessionId]);
    
    // 清理用户登录状态相关缓存(若有)
    Yii::app()->cache->delete('user_login_status_' . $sessionId);
}

方案二:文件存储会话(默认方式)

Yii默认将会话存储在服务器临时目录(可通过php.ini的session.save_path或Yii配置调整):

1. 遍历会话文件查找目标

$targetToken = 'abcd';
$matchedSessionIds = [];
$sessionDir = Yii::app()->session->savePath;

// 遍历会话目录下的所有会话文件(默认前缀为sess_)
$sessionFiles = glob($sessionDir . '/sess_*');
foreach ($sessionFiles as $file) {
    $sessionContent = file_get_contents($file);
    if (!$sessionContent) continue;
    
    // 反序列化会话数据
    $sessionAttributes = unserialize($sessionContent);
    if (isset($sessionAttributes['access_token']) && $sessionAttributes['access_token'] === $targetToken) {
        // 提取会话ID(去除文件名前缀sess_)
        $sessionId = substr(basename($file), 5);
        $matchedSessionIds[] = $sessionId;
        break;
    }
}

2. 销毁会话

foreach ($matchedSessionIds as $sessionId) {
    // 删除会话文件
    unlink($sessionDir . '/sess_' . $sessionId);
    
    // 清理关联缓存
    Yii::app()->cache->delete('user_login_status_' . $sessionId);
}

优化建议

  • 提前映射token与会话ID:用户登录生成access token时,将token和会话ID存入单独的映射表(如token_session_map),后续查找只需查询该表,无需遍历所有会话,大幅提升效率。
  • 请求合法性校验:IDP发起的登出请求必须做身份验证(如签名校验),防止恶意销毁会话。
  • 并发处理:销毁会话时加锁,避免多请求同时操作导致的数据不一致。

内容的提问来源于stack exchange,提问作者Lajos Arpad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:21:12