oidc-client中silent_renew.html的token未更新问题排查
解决方案
问题核心
静默刷新成功后,主应用未感知到用户信息(含新token)的更新,且silent_renew.html内的UserManager未使用与主应用一致的配置,导致状态无法同步。
步骤1:统一silent_renew.html的UserManager配置
silent_renew.html中的Oidc.UserManager必须传入和主应用完全一致的配置,否则无法与认证服务器正确交互,也无法将更新后的用户信息同步回主应用。修改后的代码如下:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.10.0/oidc-client.js"></script> <script> // 配置需与主应用AuthProvider内的userManagerConfig完全匹配 const config = { clientId: 'my_client_id', responseType: 'code', redirectUri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/callback`, scope: 'openid profile', authority: 'my_sso_authority', silentRedirectUri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/silent_renew.html`, automaticSilentRenew: true, loadUserInfo: true }; new Oidc.UserManager(config) .signinSilentCallback() .then(() => { console.log('静默刷新成功'); window.close(); // 可选:刷新完成后关闭iframe }) .catch(err => { console.error('静默刷新失败:', err); }); </script>
步骤2:主应用监听用户更新事件
onSignIn仅在主动登录时触发,静默刷新成功后,oidc-react会触发userLoaded或userUpdated事件,需在主应用中监听这些事件来更新sessionStorage和Redux状态:
import { AuthProvider, AuthProviderProps, useOidc } from 'oidc-react'; import { useEffect } from 'react'; const AuthWrapper = ({ children }: { children: React.ReactNode }) => { const dispatch = useAppDispatch(); const { user } = useOidc(); // 监听用户信息变化(包含静默刷新后的更新) useEffect(() => { if (user) { console.log('用户信息更新', user); sessionStorage.setItem('token', user.id_token); dispatch(loadtToken(user.id_token)); } }, [user, dispatch]); const userManagerConfig: AuthProviderProps = { clientId: 'my_client_id', responseType: 'code', redirectUri: `${window.location.protocol}//${window.location.hostname}${ window.location.port ? `:${window.location.port}` : '' }/callback`, scope: 'openid profile', authority: 'my_sso_authority', silentRedirectUri: `${window.location.protocol}//${ window.location.hostname }${ window.location.port ? `:${window.location.port}` : '' }/silent_renew.html`, automaticSilentRenew: true, loadUserInfo: true, autoSignIn: true, onSignIn: (user: any) => { console.log('主动登录成功', user); sessionStorage.setItem('token', user.id_token); dispatch(loadtToken(user.id_token)); } }; return <AuthProvider {...userManagerConfig}>{children}</AuthProvider>; };
步骤3:避免在silent_renew.html中调用signinSilent
signinSilent是主应用触发静默刷新的方法,silent_renew.html仅需处理刷新后的回调,只需调用signinSilentCallback即可,调用signinSilent会引发循环刷新或错误。
额外注意事项
- 确保
silent_renew.html放置在主应用根目录,与配置中的silentRedirectUri完全匹配; - 检查认证服务器是否已将
silentRedirectUri添加至允许的回调列表; - 确认oidc-client版本与oidc-react依赖版本兼容(当前使用的oidc-client 1.10.0需匹配oidc-react的兼容版本)。
内容的提问来源于stack exchange,提问作者ivkremer
相关产品推荐
相关产品推荐

