這是我目前使用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。
希望有幫助。