简体   繁体   English

使用Keycloak和React路由器在单个Web应用程序上同时拥有公共和私有路由的最佳方法?

[英]Best way to proceed to have both public and private routes on a single web app using Keycloak and React router?

I had a web app where you had to be authentified to see the content. 我有一个Web应用程序,必须对您进行身份验证才能查看内容。 First thing you saw entering the website was the Keycloak login page rendered in Login.js , once you were logged in, you had access to Routes.js . 首先你看到进入网站于Login.js呈现Keycloak登录页面,一旦你登录后,你有机会访问Routes.js。 Now I have to add public routes to this same application and I'm not sure how to proceed. 现在,我必须将公用路由添加到该相同的应用程序,并且不确定如何继续。 Here's what I have so far. 到目前为止,这就是我所拥有的。

Index.js Index.js

  <Suspense fallback='loading'>
    <BrowserRouter>
      <PublicRoutes/>
    </BrowserRouter>
  </Suspense>

PublicRoutes.js PublicRoutes.js

    return ( 
        <Switch>
            <Route exact path="/" render={() => <Redirect to="/signup"/>}
            />
            <Route exact path="/signup" render={() => <SignupPage header={HeaderNav}/>}
            />
            <Route exact path="/login" render={() => <Login/>}
            />
        </Switch>
    );

Login.js Login.js

if(this.state.keycloak) {
  if(this.state.authenticated) return (
    <Routes keycloak={this.state.keycloak}/>
  ); else return (<div>Unable to authenticate!</div>)
}
return (
  <div>Loading, please wait...</div>
);

Routes.js Routes.js

        <Switch>
            <Route exact path="/" render={() => <Redirect to="/home"/>}
            />
            <Route exact path="/home" render={() => <HomePage header={HeaderNav} sidebar={Sidebar}/>}
            />
            <Route exact path="/catalog" render={() => <CatalogPage header={HeaderNav} sidebar={Sidebar}/>}
            />
            <Route exact path="/query" render={() => <QueryPage header={HeaderNav} sidebar={Sidebar}/>}
            />
            <Route exact path="/workshop" render={() => <WorkshopPage header={HeaderNav} sidebar={Sidebar}/>}
            />
            <Route exact path="/dashboard/stats" render={() => <StatsPage header={HeaderNav} sidebar={Sidebar} keycloak={this.props.keycloak}/>}
            />
            <Route exact path="/dashboard/keys" render={() => <KeysPage header={HeaderNav} sidebar={Sidebar} keycloak={this.props.keycloak}/>}
            />
            <Route exact path="/dashboard/consumption" render={() => <ConsumptionPage header={HeaderNav} sidebar={Sidebar} keycloak={this.props.keycloak}/>}
            />
            <Route exact path="/faq" render={() => <HelpPage header={HeaderNav} sidebar={Sidebar}/>}
            />
            <Route exact path="/contact_us" render={() => <ContactPage header={HeaderNav} sidebar={Sidebar}/>}
            />
            <Redirect from="/login" to="/home"/>
        </Switch>

What I'd like is that the Routes.js file takes over the PublicRoutes.js file when the user is authentified. 我想要的是,在对用户进行身份验证时,Routes.js文件将接管PublicRoutes.js文件。 Right now, when the user logs in, he can still only see the public routes content. 现在,当用户登录时,他仍然只能看到公共路线的内容。

Try lifting state up. 尝试提升状态。 Maybe Index.js can switch between 2 sets of routers? 也许Index.js可以在2套路由器之间切换?

You can pass state (Keycloak object) or callbacks (handleLogin) for Login.js if you need to 如果需要,可以为Login.js传递状态(Keycloak对象)或回调(handleLogin)

Example: 例:

render() {
   const { keycloak, authenticated } = this.state;
   return 

   <div>
     {authenticated ? (
       <Secured keycloak={keycloak} />
      ) : (
       <Public handleLogin={this.handleLogin} />
     )}
   </div>
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM