授权路由与未授权路由reactjs未正确加载

时间:2020-04-28 01:30:21

标签: javascript reactjs

我无法理解为什么我的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

2 个答案:

答案 0 :(得分:1)

isAuthenticated()是异步的,当前返回void。您必须使isAuthenticated返回布尔值的承诺。

具有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 };

答案 1 :(得分:0)

我认为问题在于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>
    );
  }
}