如何实现Keycloak跨多域(Angular&React)实时会话登出同步?
Keycloak跨多域实时会话登出同步实现方案
核心前提说明
两个子域名应用(dev.app-test.com和dev-new.app-test.com)同属父域app-test.com,Keycloak的跨域同步依赖共享会话Cookie+前端状态监听的组合方案,以下是具体实现步骤:
1. 配置Keycloak Realm的跨域Cookie
登录Keycloak管理控制台,进入目标Realm的Realm Settings -> Cookies页面:
- 设置
Cookie Domain为父域名.app-test.com(必须以点开头,确保所有子域名能共享该Cookie) - 根据部署环境调整
Secure Cookie和HttpOnly Cookie:HTTPS环境建议开启Secure Cookie,增强安全性;HttpOnly Cookie保持默认开启即可,防止XSS窃取会话
2. 前端应用针对性调整
Angular应用(基于keycloak-angular)
- 确保初始化Keycloak时开启
checkLoginIframe(默认已开启,若手动配置需确认),该iframe会定期轮询Keycloak会话状态 - 监听Keycloak的
onAuthLogout事件,触发应用内的登出清理逻辑:
import { KeycloakService } from 'keycloak-angular'; constructor(private keycloakService: KeycloakService) { this.keycloakService.keycloakEvents$.subscribe(event => { if (event.type === 'onAuthLogout') { localStorage.clear(); window.location.href = '/login'; } }); }
React/Next.js应用
- 若使用自定义Keycloak实例,初始化后监听
onAuthLogout事件;若用next-auth集成Keycloak,需在回调中处理全局登出 - 登出时调用Keycloak的
logout方法,确保销毁全局会话:
import Keycloak from 'keycloak-js'; const keycloak = new Keycloak('/keycloak.json'); // 初始化后监听登出事件 keycloak.onAuthLogout = () => { sessionStorage.clear(); window.location.href = '/login'; }; // 自定义登出方法 const handleLogout = async () => { await keycloak.logout({ redirectUri: `${window.location.origin}/login` }); };
3. 增强实时性(可选)
默认的iframe轮询间隔为30秒,若需要更实时的同步,可添加主动检查逻辑:
- 在Angular中设置定时任务,主动验证会话状态:
setInterval(async () => { const isLoggedIn = await this.keycloakService.isLoggedIn(); if (!isLoggedIn) { await this.keycloakService.logout(); } }, 10000); // 每10秒检查一次
4. 验证环节
- 测试从任一应用登出,检查另一应用是否自动触发登出跳转
- 查看浏览器Cookie面板,确认
KEYCLOAK_SESSION等Cookie的Domain为.app-test.com - 登录Keycloak控制台的Sessions页面,确认用户会话在登出后被销毁
内容的提问来源于stack exchange,提问作者Anuj Gupta
相关产品推荐
相关产品推荐

