Keycloak 20.0.3在React应用中登出失败(重定向URL无效)
Keycloak React应用登出失败问题排查
问题描述
使用Keycloak对React应用做身份认证,点击登出按钮后无法完成登出操作。已在Keycloak管理控制台配置登出重定向URL为http://localhost:7171,点击登出后跳转的URL如下:
http://localhost:8080/realms/hype/protocol/openid-connect/logout?client_id=hypeclient&post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A7171%2F&id_token_hint=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJZRHVhc0pTT0dIOUh2ZnRvZGNhRktmRkxuOEZuWmkzSVN3eVBQenlzazFVIn0.eyJleHAiOjE2NzU1NjU1ODUsImlhdCI6MTY3NTU2NTI4NSwiYXV0aF90aW1lIjoxNjc1NTY1MjcyLCJqdGkiOiI1MjEyODZlZS1hNThiLTRhMTUtYTgyZS1jODU2ZmE4NWVkZTEiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL2h5cGUiLCJhdWQiOiJoeXBlY2xpZW50Iiwic3ViIjoiYzJhZTJiZWYtMjg2ZC00MDgzLTk3YTktMWEyM2YxNzQ4YzE0IiwidHlwIjoiSUQiLCJhenAiOiJoeXBlY2xpZW50Iiwibm9uY2UiOiI3NGUyMTk3Ni0zNzcwLTQzNWEtOTEzMC1lNGU2YWUyY2I4ZTIiLCJzZXNzaW9uX3N0YXRlIjoiYzAxZWJlYTEtMjAwYS00YzU3LTg2NTgtNjYyYTdjOTA5OThkIiwiYXRfaGFzaCI6IjNPczlxc0NucFdmYnFuRkNlZ1docmciLCJhY3IiOiIwIiwic2lkIjoiYzAxZWJlYTEtMjAwYS00YzU3LTg2NTgtNjYyYTdjOTA5OThkIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoia2FyYW4gc2hhaCIsInByZWZlcnJlZF91c2VybmFtZSI6ImthcmFuIiwiZ2l2ZW5fbmFtZSI6ImthcmFuIiwiZmFtaWx5X25hbWUiOiJzaGFoIn0.TFCh-dPE4h8HKpAapNv4socR7uAsKDnuVpqLiaZCguu1Vyztn_sUkrbaqFKJDeoIZv3XDzBDM5MezMvyRRkmiRIQTIbiTlYGgcNA5UkcwbeKioaowCWqYqyjG7A3D0lKNjf0MAF6PmWVrPJVbm8hYtQMVDHwWQ2vFTShnmMRJ2iTf4IeT1DDLANrLh3tMXeYMF2f9ZmvtNS72O-BICkD4uXPSyMiqnDgj_52UAdkEaLgkuv31TAYDAeVef-Rly8n7K5LG1MWytB2_-WrhwXwfxjymc9RH55Iy-1tvLUFceigO7XwQzffZYK5uJ9PXkbg3hlkr6QLVSXsiu8RYKQu9w
环境版本
Keycloak 20.0.3 Keycloak.js 20.0.3(npm安装) React 18.2
应用代码配置
App.js
import React from "react"; import { ReactKeycloakProvider } from "@react-keycloak/web"; import keycloak from "../Keycloak"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import Nav from "../components/Nav"; import WelcomePage from "../pages/Homepage"; import SecuredPage from "../pages/Securedpage"; import PrivateRoute from "../helpers/PrivateRoute"; function App() { return ( <div> <ReactKeycloakProvider authClient={keycloak}> <Nav /> <BrowserRouter> <Routes> <Route exact path="/" element={<WelcomePage />} /> <Route path="/secured" element={<PrivateRoute> <SecuredPage /> </PrivateRoute>}/> </Routes> </BrowserRouter> </ReactKeycloakProvider> </div> ); } export default App;
Nav.js
import React from "react"; import { useKeycloak } from "@react-keycloak/web"; const Nav = () => { const { keycloak, initialized } = useKeycloak(); function loginHelper(){ console.log("login clicked"); keycloak.login(); }; function logoutHelper(){ console.log("login clicked"); keycloak.logout(); }; return ( <div> <div className="top-0 w-full flex flex-wrap"> <section className="x-auto"> <nav className="flex justify-between bg-gray-200 text-blue-800 w-screen"> <div className="px-5 xl:px-12 py-6 flex w-full items-center"> <h1 className="text-3xl font-bold font-heading"> Keycloak React AUTH. </h1> <ul className="hidden md:flex px-4 mx-auto font-semibold font-heading space-x-12"> <li> <a className="hover:text-blue-800" href="/"> Home </a> </li> <li> <a className="hover:text-blue-800" href="/secured"> Secured Page </a> </li> </ul> <div className="hidden xl:flex items-center space-x-5"> <div className="hover:text-gray-200"> {!keycloak.authenticated && ( <button type="button" className="text-blue-800" onClick={() => loginHelper()} > Login </button> )} {!!keycloak.authenticated && ( <button type="button" className="text-blue-800" onClick={() => logoutHelper()} > Logout ({keycloak.tokenParsed.preferred_username}) </button> )} </div> </div> </div> </nav> </section> </div> </div> ); }; export default Nav;
Keycloak.js
import Keycloak from "keycloak-js"; const keycloak = new Keycloak({ url: "http://localhost:8080", realm: "hype", clientId: "hypeclient", }); export default keycloak;
PrivateRoute.js
import { useKeycloak } from "@react-keycloak/web"; const PrivateRoute = ({ children }) => { const { keycloak } = useKeycloak(); const isLoggedIn = keycloak.authenticated; console.log("checking auth access " + isLoggedIn); return isLoggedIn ? children : null; }; export default PrivateRoute;
已尝试操作
曾参考相关登出问题方案,但未解决问题。Keycloak管理控制台配置截图如下:
解决步骤
1. 显式指定登出重定向URL
修改Nav.js中的logoutHelper方法,调用logout时传入和控制台配置一致的重定向地址:
function logoutHelper(){ console.log("logout clicked"); keycloak.logout({ redirectUri: "http://localhost:7171" }); };
2. 检查Keycloak客户端配置
- 确认Valid Post Logout Redirect URIs中添加
http://localhost:7171/*(使用通配符覆盖所有子路径) - 确保客户端的Standard Flow Enabled处于开启状态
- 确认客户端Access Type设置为
public(当前代码未配置secret,符合public客户端特征)
3. 同步本地认证状态
在ReactKeycloakProvider中添加登出回调,强制刷新页面确保状态同步:
<ReactKeycloakProvider authClient={keycloak} onLogout={() => { window.location.reload(); }} > {/* 原有组件内容 */} </ReactKeycloakProvider>
4. 修正调试日志
将Nav.js中logoutHelper的日志内容改为logout clicked,方便后续调试排查。
内容的提问来源于stack exchange,提问作者ksernow
相关产品推荐
相关产品推荐

