【问题标题】:authorized route vs unauthorized routes reactjs not properly loading授权路线与未授权路线 reactjs 未正确加载
【发布时间】:2020-04-28 01:30:21
【问题描述】:

我无法理解为什么我的 AuthorizedUnauthorized 路由无法正常运行。以下是我的路由设置方式:

class App extends Component {

  render() {
    return (
      <HashRouter>
          <React.Suspense fallback={loading()}>
            <Switch>
              <UnauthenticatedRoute exact path="/login" name="Login Page" component={Login} />
              <Route exact path="/register" name="Register Page" component={Register} />
              <Route exact path="/404" name="Page 404" component={Page404} />
              <Route exact path="/500" name="Page 500" component={Page500} />
              <AuthenticatedRoute path="/" name="Home" component={DefaultLayout} />
            </Switch>
          </React.Suspense>
      </HashRouter>
    );
  }
}

export default App;

我有一个auth.js,它包含所有这些路由类型以及检查 JWT 令牌是否有效:

import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { Api } from './api'

const isAuthenticated = () => {
  Api.isActiveToken(sessionStorage.getItem('token')).then(
    (response) => {
      console.log(response)
      return response.ok
    },
    (error) => {
      return false
    }
  )
}

const AuthenticatedRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    isAuthenticated()
      ? <Component {...props} />
      : <Redirect to='/login' />
  )} />
);

const UnauthenticatedRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    !isAuthenticated()
      ? <Component {...props} />
      : <Redirect to='/' />
  )} />
);

export { AuthenticatedRoute, UnauthenticatedRoute }

console.log(response) 的外观如下:

Response {type: "cors", url: "http://xxx/api/v1/login/validate-token", redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://xxx/api/v1/login/validate-token"
__proto__: Response

我的sessionStorage 持有令牌就好了。我做错了什么以至于我的路线永远不会重定向/允许我到AuthorizedRoute

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    isAuthenticated() 是异步的,当前返回 void。你必须让 isAuthenticated 返回一个 Promise of a boolean。

    一旦你有 isAuthenticated 返回一个值,你就需要使用一个效果和状态来从 Promise 中提取实际值。

    import React, { useState, useEffect } from 'react';
    import { Redirect, Route } from 'react-router-dom';
    import { Api } from './api';
    
    const isAuthenticated = async () => {
      try {
        const response = await Api.isActiveToken(sessionStorage.getItem('token'));
        return response.ok;
      } catch (error) {
        return false;
      }
    };
    
    const AuthenticatedRoute = ({ component: Component, ...rest }) => {
      const [authenticated, setAuthenticated] = useState(null);
      useEffect(() => {
        isAuthenticated().then((bool) => setAuthenticated(bool));
      }, []);
    
      return (
        <Route
          {...rest}
          render={(props) => {
            if (authenticated === null) return '...loading';
            return authenticated ? <Component {...props} /> : <Redirect to="/login" />;
          }}
        />
      );
    };
    
    const UnauthenticatedRoute = ({ component: Component, ...rest }) => {
      const [authenticated, setAuthenticated] = useState(null);
      useEffect(() => {
        isAuthenticated().then((bool) => setAuthenticated(bool));
      }, []);
      return (
        <Route
          {...rest}
          render={(props) => {
            if (authenticated === null) return '...loading';
            return !authenticated ? <Component {...props} /> : <Redirect to="/" />;
          }}
        />
      );
    };
    
    export { AuthenticatedRoute, UnauthenticatedRoute };
    

    【讨论】:

    • 这会导致:Expected an assignment or function call and instead saw an expression
    • 我在我忘记的退货声明中添加了
    • 哎呀,没关系,.. 这可能有效,1 秒!
    • 好的,所以现在当我使用sessionStorage.removeItem('token'); 注销时,我会通过async await 循环尝试调用我的后端
    • 我还意外地将!isAuthenticated 留在了UnauthenticatedRoute 而不是! authenticated,这可能导致它不断重定向到“/”,但除此之外,我没有看到在哪里无限循环是从。
    【解决方案2】:

    我认为问题在于 Switch 组件需要某些类型的子组件,而您正在向它传递一个不同的组件类型 AuthenticatedRoute 它可能无法处理。您可以将组件转换为仅返回 Route 元素的渲染函数,而不是创建新的组件类型,以便 Switch 仅包含路由。

    const renderAuthenticatedRoute = ({ component: Component, ...rest }) => (
      <Route {...rest} render={(props) => (
        isAuthenticated()
          ? <Component {...props} />
          : <Redirect to='/login' />
      )} />
    );
    
    const renderUnauthenticatedRoute = ({ component: Component, ...rest }) => (
      <Route {...rest} render={(props) => (
        !isAuthenticated()
          ? <Component {...props} />
          : <Redirect to='/' />
      )} />
    );
    
    class App extends Component {
      render() {
        return (
          <HashRouter>
              <React.Suspense fallback={loading()}>
                <Switch>
                  { 
                    renderUnauthenticatedRoute({ 
                      exact: true, 
                      path: "/login", 
                      name: "Login Page",
                      component: Login
                    })
                  }
                  <Route exact path="/register" name="Register Page" component={Register} />
                  <Route exact path="/404" name="Page 404" component={Page404} />
                  <Route exact path="/500" name="Page 500" component={Page500} />
                  { 
                    renderAuthenticatedRoute({
                      path: "/",
                      name: "Home",
                      component: DefaultLayout
                    }) 
                  }
                </Switch>
              </React.Suspense>
          </HashRouter>
        );
      }
    }
    

    【讨论】:

    • 编译正确,但由于某种原因仍将我重定向回/login
    猜你喜欢
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2013-11-01
    • 2019-03-07
    相关资源
    最近更新 更多