Angular10 OIDC Client对接Identity Server4设置max_age后静默令牌续期失效求解
问题根因
你当前的配置错误点在于把prompt="login"和max_age设为了全局配置,会被所有OIDC请求继承:
- 静默令牌续期要求请求必须携带
prompt=none参数,才能让身份提供商(IDP)无交互返回令牌,你全局配置的prompt=login覆盖了静默请求的默认参数,导致IDP强制要求用户交互登录,静默续期直接失败。 - 全局生效的
max_age也会导致静默续期时频繁触发重新认证,进一步打断正常续期流程。
解决方案
方案一:修改存储介质实现关闭标签页/浏览器即重登(最简单)
如果你的需求是只要关闭浏览器或者标签页就必须重新登录,不需要依赖IDP侧的会话时效判断,直接修改OIDC UserManager的存储为sessionStorage即可。
sessionStorage的特性是标签页关闭、浏览器关闭后自动清空存储内容,重新打开应用时没有缓存的用户信息,会直接触发登录流程,完全不需要配置max_age和prompt参数,也不会影响静默续期。
配置代码示例:
// 注意需要从oidc-client包中导入WebStorageStateStore import { UserManager, WebStorageStateStore } from 'oidc-client'; const settings: any = await response.json(); settings.automaticSilentRenew = true; settings.includeIdTokenInSilentRenew = true; settings.accessTokenExpiringNotificationTime = 30; // default 60 settings.checkSessionInterval = 5000; // default 2000; settings.silentRequestTimeout = 20000;// default: 10000 settings.monitorSession = true; settings.loadUserInfo = true; settings.filterProtocolClaims = true; // 新增:配置存储为sessionStorage,关闭标签页/浏览器自动清空 settings.userStore = new WebStorageStateStore({ store: window.sessionStorage }); // 删除全局的max_age和prompt配置 // settings.max_age = 10; // settings.prompt="login" this.userManager = new UserManager(settings);
方案二:保留max_age校验,区分不同请求的参数
如果你需要依赖IDP侧的max_age校验逻辑(比如要求用户指定时长无操作就需要重新认证),则不要全局配置max_age和prompt,仅在首次登录请求时携带对应参数,静默续期时使用独立的参数配置:
- 移除全局的
max_age和prompt配置 - 发起首次登录时给
signinRedirect传入额外参数:
// 登录按钮触发的登录逻辑示例 public login() { this.userManager.signinRedirect({ max_age: 10, prompt: 'login' }); }
- 给静默续期配置独立的额外参数,强制携带
prompt=none:
settings.silentRequestExtraParams = { prompt: 'none' };
验证方法
- 静默续期验证:打开浏览器控制台筛选网络请求,找到静默续期的authorize请求,检查参数中
prompt的值为none,令牌到期后会自动续期不会跳转登录。 - 关闭重登验证:关闭浏览器/标签页后重新打开应用,会自动跳转到登录页。
内容的提问来源于stack exchange,提问作者San Jaisy
相关产品推荐
相关产品推荐

