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

如何从example.com域检查同浏览器内sso.example.com的Keycloak SSO会话存在性?

跨域检查Keycloak SSO会话的可行方案

因为KEYCLOAK_SESSION Cookie属于sso.example.com域,example.com的前端代码无法直接读取,所以得换官方推荐的跨域会话检查方式,以下是两种实用方案:

方案一:用Keycloak登录状态iframe(前端直接实现)

Keycloak自带专门处理跨域会话检查的iframe页面,通过postMessage和父页面通信,这是官方主推的方式,步骤如下:

  1. 嵌入检查iframe
    在example.com的页面中加入隐藏的iframe,指向Keycloak的登录状态端点:
<iframe id="kc-session-check" src="https://sso.example.com/realms/你的Realm名称/protocol/openid-connect/login-status-iframe.html" style="display: none;"></iframe>
  1. 前端监听并触发会话检查
    添加JS代码,通过postMessage和iframe交互,获取会话状态:
// 监听iframe发来的会话状态消息
window.addEventListener('message', (event) => {
  // 一定要验证消息来源,防止恶意请求
  if (event.origin !== 'https://sso.example.com') return;

  const msg = JSON.parse(event.data);
  if (msg.type === 'login-status') {
    // 没有SSO会话就重定向到登录页
    if (!msg.loggedIn) {
      const loginUrl = `https://sso.example.com/realms/你的Realm名称/protocol/openid-connect/auth?client_id=你的Example客户端ID&redirect_uri=https://example.com/回调路径&response_type=code`;
      window.location.href = loginUrl;
    }
  }
});

// 页面加载后主动向iframe发请求
window.addEventListener('load', () => {
  const iframe = document.getElementById('kc-session-check');
  iframe.contentWindow.postMessage(JSON.stringify({ type: 'login-status-request' }), 'https://sso.example.com');
});
  1. Keycloak后台配置
    进入你的Realm → 客户端 → 选择example.com对应的客户端 → 在「Web Origins」中添加https://example.com(测试阶段可以填*,生产环境必须指定具体域名),确保跨域通信被允许。

方案二:后端代理检查请求(更安全)

如果担心前端postMessage的安全性,或者需要结合后端业务逻辑,可以让example.com的后端去请求Keycloak的会话端点,后端之间没有跨域限制:

  1. 后端编写检查接口
    以Node.js/Express为例,转发用户浏览器的Cookie到Keycloak的会话状态接口:
app.get('/api/check-keycloak-session', async (req, res) => {
  try {
    const kcSessionUrl = 'https://sso.example.com/realms/你的Realm名称/protocol/openid-connect/session-status';
    const response = await fetch(kcSessionUrl, {
      headers: {
        // 转发用户浏览器的Cookie,包含Keycloak的会话Cookie
        Cookie: req.headers.cookie || ''
      },
      credentials: 'include'
    });

    const sessionData = await response.json();
    // 根据返回结果判断是否存在有效会话
    const hasValidSession = sessionData.loggedIn === true;
    res.json({ hasValidSession });
  } catch (err) {
    // 请求失败默认视为无会话
    res.json({ hasValidSession: false });
  }
});
  1. 前端调用后端接口
fetch('/api/check-keycloak-session')
  .then(res => res.json())
  .then(data => {
    if (!data.hasValidSession) {
      const loginUrl = `https://sso.example.com/realms/你的Realm名称/protocol/openid-connect/auth?client_id=你的Example客户端ID&redirect_uri=https://example.com/回调路径&response_type=code`;
      window.location.href = loginUrl;
    }
  });

关键注意事项

  • Cookie设置:在Keycloak后台Realm设置 → Cookies → 把SameSite属性设为None,同时开启Secure(必须用HTTPS,否则跨域Cookie无法传递)。
  • HTTPS强制:跨域会话检查在HTTP环境下会有各种限制,生产环境必须全链路用HTTPS。
  • Keycloak 18兼容性:以上方案完全适配Keycloak 18(Quarkus版本),配置路径和老版本一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:52:50