尽管我的本地 Keycloak 服务器上有一个活动会话,React 应用程序仍然停留在加载页面上

问题描述 投票:0回答:1

我正在本地开发一个 React 应用程序,并使用 Keycloak 来管理身份验证。我使用keycloak.js包和react-keycloak包从react应用程序访问Keycloak服务器。

当用户未登录时,唯一可访问的路由应该是“/”和“/login”。 “/”路由呈现登陆页面,而“/login”路由重定向到 Keycloak 登录页面。这些路由存储在 PublicView 对象中。

如果用户登录,应该可以访问更多路由,例如“/collections”。例如,登录后,用户应重定向到“/”路由,然后重定向到“/collections”页面,而不是呈现登陆页面。

目前,React 应用程序的功能如用户未登录时所述。此外,登录后,用户会正确重定向到“/”路由,然后重定向到“/collections”路由并显示相关内容。

但是,如果我在浏览器中手动输入任何 PrivateView 路由(即重新加载单页应用程序),它只会显示“授权...”加载消息。它应该做的是根据 PrivateView 对象提供 URI。

虽然这表明客户端尚未初始化,但我知道身份验证一定已成功,因为应用程序的 return 语句中的行

{console.log("rendering:", isAuth)}
正确执行: [console after accessing any URI whilst being logged in] 然而,如图所示,会抛出 404 错误,就好像找不到 URI 的页面一样。我已将 404 错误追溯到 SharedView 对象中的
<NotFound errorMessage={new Error("404 not found")}/>
组件。这是意外的,因为我重新加载/访问的所有路由都是在 PrivateView 对象中指定的。

有人知道我如何纠正这种行为吗?

以下是所有相关代码:

App.js:

import { Routes, Route, Navigate } from "react-router-dom"
import { useKeycloak } from "@react-keycloak/web"

// Components
import PrimaryLayout from "./components/layouts/PrimaryLayout"

// Pages
import About from "./pages/About/index"
import Collections from "./pages/Collections/index"
import Artworks from "./pages/Artworks/index"
import ArtworkPopup from "./pages/ArtworkPopup"
import Contact from "./pages/Contact/index"
import Login from "./pages/Login/index"
import Logout from "./pages/Logout/index"
import Landing from "./pages/Landing/index"
import NotFound from "./pages/NotFound/index"
import Tests from "./pages/__tests__/index"

// Styles
import './global.css'

function App() {
    const { keycloak, initialized } = useKeycloak()
    const isAuth = keycloak.authenticated

    const PrivateView = (
        <>
            <Route element={ <PrimaryLayout /> } >
                <Route path="about" element={ <About /> } />

                <Route path="collections" >
                    <Route index element={ <Collections /> } />
                    <Route path=":collectionId" element={ <Navigate replace to="a" /> } />

                    <Route path=":collectionId/a" element={ <Artworks /> } >
                    <Route path=":artworkId" element={ <ArtworkPopup />} />
                    </Route>
                </Route>

                <Route path="contact" element={ <Contact /> } />
                <Route path="logout" element={ <Logout /> } />
            </Route>

            <Route path="/" element={ <Navigate replace to="collections" /> } />
        </> 
    )

    const PublicView = (
        <>
            <Route path="/" element={ <Landing /> } />
            <Route path="login" element={ <Login /> } />
        </>
    )

    const SharedView = (
        <>
            <Route path="tests" element={ <Tests /> } />
            <Route path="*" element={ <NotFound errorMessage={new Error("404 not found")}/> } />
        </>
    )

    if (!initialized) {
        console.log("Still loading")
        return <div>Authenticating...</div>
    }

    return (
        <Routes>
            {console.log("rendering:", isAuth)}
            {isAuth ? PrivateView : PublicView}
            {SharedView}
        </Routes>
    )
}

export default App

登录.js:

import { useKeycloak } from "@react-keycloak/web"
import keycloakLogin from "../../data/keycloakLogin"

function Login() {
    const { keycloak } = useKeycloak()

    keycloak.login({redirectUri: "http://localhost:3001/")

    return (
        <main className="main">
            <div className="page-description">
                <h1 className="page-description__name">Login</h1>
            </div>
            <div>Redirecting to login...</div>
        </main>
    )
}

export default Login

index.js:

import React from "react"
import ReactDOM from 'react-dom/client'
import { ReactKeycloakProvider } from "@react-keycloak/web"
import { BrowserRouter } from "react-router-dom"
import './index.css'

// APP
import App from './App'

// Config
import keycloakClient from "./data/keycloakClient"
import keycloakInit from "./data/keycloakInit"

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(

    /* IMPORTANT

    I wrapped the ReactKeycloakProvider around the React.StrictMode component to prevent double initialisation of the Keycloak client.

    */
    <ReactKeycloakProvider authClient={keycloakClient} initOptions={
        onLoad: 'check-sso',
        silentCheckSsoRedirectUri: `${window.location.origin}/silent-check-sso.html`,
        pkceMethod: "S256"
    }>
        <React.StrictMode>
            <BrowserRouter>
                <App />
            </BrowserRouter>
        </React.StrictMode>
    </ReactKeycloakProvider>
);
javascript reactjs jsx keycloak
1个回答
0
投票

BRUHH 好吧,这很令人沮丧,因为花了很长时间才弄清楚这个简单的错误,但基本上我初始化客户端的方式是错误的。我使用了silentSSO 方法。无论出于何种原因,这都不允许客户端正确进行身份验证,并且陷入循环中。我通过删除 ReactKeycloakProvider 中的silentCheckSsoRedirectUri选项解决了这个问题:

initOptions={
        onLoad: 'check-sso',
        // silentCheckSsoRedirectUri: `${window.location.origin}/silent-check-sso.html`,
        pkceMethod: "S256"
    }
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.