type
status
date
slug
summary
category
tags
create_time
Jun 2, 2025 04:55 PM
icon
password
my_create_time
📌 背景
nCalendar 项目中,统一认证采用 Dex 作为 OpenID Connect Provider,多个系统通过 Dex 实现单点登录:
- 例如:nCalendar 管理后台、订阅配置界面、用户门户等
- 每个系统作为一个 OIDC 客户端,通过授权码模式登录
- 用户首次登录任一系统后,其余系统可自动完成无感登录(silent login)
问题出现:
用户在某系统点击“退出登录”按钮,仅退出了该前端应用,但 Dex 仍保存全局会话 Cookie,用户访问其他系统时仍视为已登录。
PS:其实 Dex 也没实现全局 Cookie,是我自己实现的一套。。。
🧩 使用场景
- 用户访问多个基于 Dex 登录的子系统
- 希望点击任一“退出登录”按钮后,同时退出 Dex 和所有已登录系统
- 提升用户安全体验,尤其在共享电脑、公用设备上的使用场景
✅ 实现目标
用户登出某个子系统后,应同时触发 Dex 的全局会话清除,其他系统重新访问将跳转登录页。
🖼️ 退出流程图

🛠️ 流程分步详解
下面详细分解统一登出流程的每一个关键步骤:
1️⃣ 用户点击“退出登录”按钮
用户在管理后台点击退出按钮后,前端不会直接跳转,而是调用应用后端的
/logout
接口。后端进行以下操作:
- 清理当前系统的 session、token 等本地登录状态;
- 构建指向 Dex 的退出 URL,通常包括以下参数:
id_token_hint
: 当前会话的 ID Token,用于标识要注销的会话;post_logout_redirect_uri
: Dex 完成登出后应跳转回的地址;state
: 可选参数,用于防止 CSRF 攻击。
2️⃣ 自定义 Dex 的隐藏 logout 页面和接口
Dex 默认未实现 RP-Initiated Logout,因此我们需手动实现:
- 一个“隐藏的登出页面”,例如
/dex/logout
- 页面内通过 JavaScript 发起对 Dex 后端
/logout
接口的请求
- 可选:根据 OpenID Connect 标准将登出 URL 通过 Discover 配置暴露,例如:
这样,前端应用在实现中也可以动态发现并获取登出接口。
3️⃣ Dex 服务端执行登出操作
在隐藏页面中调用 Dex 后端接口时,会完成如下操作:
- 校验
id_token_hint
的合法性;
- 清除 Dex 维护的“全局 Cookie”(我们自定义实现的);
- 依次回调所有注册应用的登出接口,确保每个子系统都能同步清理本地状态;
- 比如:POST 请求到
https://admin.ncalendar.com/logout
,https://portal.ncalendar.com/logout
等
这一机制参考了 OIDC 的 Front-Channel 或 Back-Channel Logout 实现模式。
4️⃣ Dex 构建跳转回应用的重定向地址
Dex 后端完成登出流程后,根据
post_logout_redirect_uri
构建返回地址。此参数由初始请求者传入,Dex 验证合法性后返回给前端隐藏页面。
5️⃣ Dex 隐藏页面重定向到应用首页
隐藏页面拿到重定向地址后,前端自动跳转回原始应用首页,至此用户“统一登出流程”圆满完成。
✅ 总结
虽然 Dex 目前尚不支持原生的统一登出与全局 Cookie 管理,但通过自定义隐藏页面、会话清理接口及各子系统回调机制,我们仍可实现:
- 统一登录体验(SSO)
- 统一登出体验(Single Logout)
- 增强安全性,保障用户数据不被滥用
这套方案不仅适用于 nCalendar,也为使用 Dex 构建 SSO 架构的其他项目提供了参考。
📎 参考文章
有关文章的任何疑问,欢迎您在底部评论区留言,一起交流~
若文章对您有帮助,欢迎 请我喝杯咖啡~
- 作者:lusyoe
- 链接:https://blog.lusyoe.com/article/dex-sso-logout
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。