如何使用Auth.js实现与Keycloak联动的单点登出功能?
解决Auth.js登出时同步Keycloak全局会话的问题
要实现从example.com登出时同时注销accounts.example.com的Keycloak会话,核心是触发Keycloak的全局登出(Single Sign-Out),而不是仅清除Auth.js的本地会话。以下是具体实现步骤:
1. 调整Auth.js的登出逻辑,调用Keycloak全局登出端点
在Auth.js的配置中,需要重写signOut回调,构造Keycloak的登出URL并引导用户跳转,完成全局会话注销后再返回网站。
以Next.js中使用Auth.js为例,配置示例如下:
import NextAuth from "next-auth"; import KeycloakProvider from "next-auth/providers/keycloak"; export const authOptions = { providers: [ KeycloakProvider({ clientId: process.env.KEYCLOAK_CLIENT_ID, clientSecret: process.env.KEYCLOAK_CLIENT_SECRET, issuer: process.env.KEYCLOAK_ISSUER, // 格式:https://accounts.example.com/realms/你的领域名 }), ], callbacks: { async signOut({ token }) { // 构造Keycloak全局登出URL const logoutUrl = new URL(`${process.env.KEYCLOAK_ISSUER}/protocol/openid-connect/logout`); // 必要参数:客户端ID、登出后跳转地址、ID Token提示(用于识别用户会话) logoutUrl.searchParams.set("client_id", process.env.KEYCLOAK_CLIENT_ID); logoutUrl.searchParams.set("post_logout_redirect_uri", `${process.env.NEXTAUTH_URL}/logout-success`); // 自定义登出成功页 logoutUrl.searchParams.set("id_token_hint", token.idToken); // 重定向到Keycloak完成全局登出 return logoutUrl.toString(); }, }, }; export default NextAuth(authOptions);
2. 配置Keycloak客户端允许全局登出
登录Keycloak管理控制台,对目标客户端进行以下配置:
- 进入你的领域 → Clients → 选择对应客户端
- 切换到
Settings标签:- 在
Logout Redirect URIs中添加你设置的登出回调地址(如https://example.com/logout-success),确保Keycloak允许登出后跳转回该地址 - 若你的应用是服务器端渲染类型,将
Access Type设置为confidential,保证客户端密钥能正常生效
- 在
- 切换到
Advanced标签,将Frontchannel Logout设置为On(可选,增强多客户端会话同步登出的可靠性)
3. 处理登出后的本地会话清除
当用户从Keycloak跳转回post_logout_redirect_uri指定的页面后,Auth.js会自动清除本地会话。如果需要手动确认,可在登出成功页调用signOut({ callbackUrl: '/' })确保本地状态完全清除。
内容的提问来源于stack exchange,提问作者Big boy
相关产品推荐
相关产品推荐

