这是我当前使用react-router-dom、oidc-client-ts、react-oidc-context和keycloak授权服务器的实现
具有以下库版本
"oidc-client-ts": "^2.2.4", "react-oidc-context": "^2.2.2",
<Route path="/protected" element={ <AuthOidcProvider> <AuthBarrier> <AppLayout /> </AuthBarrier> </AuthOidcProvider> } > <Route path={HOME_PATH} element={<Home />} /> </Route>
AuthOidcProvider 组件用于提供身份验证上下文
interface AuthOidcProviderProps { children: ReactNode; } const AuthOidcProvider: FC<AuthOidcProviderProps> = ({ children, }): JSX.Element => { // const navigate = useNavigate(); const oidcConfig = { redirect_uri: OAUTH2_REDIRECT_URI, post_logout_redirect_uri: OAUTH2_POST_LOGOUT_REDIRECT_URI, silent_redirect_uri: OAUTH2_POST_LOGOUT_REDIRECT_URI, authority: OAUTH2_AUTHORITY, client_id: OAUTH2_CLIENT_ID, scope: "openid profile email", automaticSilentRenew: true, onSigninCallback() { // You must provide an implementation of onSigninCallback to oidcConfig to remove the payload // from the URL upon successful login. // Otherwise if you refresh the page and the payload is still there, signinSilent - which handles renewing your token - won't work. console.log("onSigninCallback()"); window.history.replaceState( {}, document.title, window.location.pathname ); }, }; return <AuthProvider {...oidcConfig}>{children}</AuthProvider>; }; export default AuthOidcProvider;
AuthBarrier 组件处理自动身份验证并阻止未经身份验证的用户
interface AuthBarrierProps { children: ReactElement; } // Automatically sign-in and silently reestablish your previous session, if you close the tab and reopen the application. const AuthBarrier: FC<AuthBarrierProps> = ({ children }): JSX.Element => { const auth = useAuth(); // automatically sign-in useEffect(() => { if ( !hasAuthParams() && !auth.isAuthenticated && !auth.activeNavigator && !auth.isLoading ) { auth.signinRedirect(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [ auth.isAuthenticated, auth.activeNavigator, auth.isLoading, auth.signinRedirect, ]); // // inactivity listener // useEffect(() => { // // the `return` is important - addAccessTokenExpiring() returns a cleanup function // return auth.events.addAccessTokenExpiring(() => { // console.log("Access token expiring..."); // // renew the access token silently // auth.signinSilent(); // console.log("Access token renewed."); // }); // // eslint-disable-next-line react-hooks/exhaustive-deps // }, [auth.events, auth.signinSilent]); switch (auth.activeNavigator) { case "signinSilent": console.log("signinSilent"); return <div>Signing you in...</div>; case "signoutRedirect": console.log("signoutRedirect"); return <div>Signing you out...</div>; } if (auth.isLoading) { return <LoadingAnimation />; } if (auth.error) { console.error(auth.error); return <LoadingAnimation />; } if (!auth.isAuthenticated) { return <LoadingAnimation />; } return <Fragment>{children}</Fragment>; }; export default AuthBarrier;
当我尝试使用auth.removeUser()注销时,我总是被重定向到“主页”页面。 在 oidcConfig 中,post_logout_redirect_uri 无效
有人有解决这个问题的例子吗?
我遇到了同样的问题并解决了在removeUser()之后调用signoutRedirect():
这样浏览器就会重定向到身份验证服务器登录页面。
我对 post_logout_redirect_uri 和 redirect_uri 使用了相同的 URI。
希望有帮助。