如何限制对react-router中路由的访问?

Tan*_*rad 64 javascript reactjs react-router

有谁知道如何限制对react-router中特定路由的访问?我想在允许访问特定路由之前检查用户是否已登录.我认为这很简单,但文档并不清楚如何做到这一点.

这是我应该在我定义<Route>组件的地方设置的,还是我应该在组件处理程序中处理它?

<Route handler={App} path="/">
  <NotFoundRoute handler={NotFound} name="not-found"/>
  <DefaultRoute handler={Login} name="login"/>
  <Route handler={Todos} name="todos"/> {/* I want this to be restricted */}
</Route>
Run Code Online (Sandbox Code Playgroud)

jay*_*air 68

接受的答案是正确的,但React团队认为Mixins是有害的(https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html).

如果有人遇到这个问题并且正在寻找推荐的方法来做到这一点,我建议使用高阶组件而不是Mixins.

以下是HOC的示例,该HOC将在继续之前检查用户是否已登录.如果用户未登录,则会将您重定向到登录页面.此组件采用被调用的prop App.js,它基本上是应用程序可以存储的标志,表示用户是否已登录.

export default function App() {
  const [isAuthenticated, userHasAuthenticated] = useState(false);

  useEffect(() => {
    onLoad();
  }, []);

  async function onLoad() {
    try {
      await Auth.currentSession();
      userHasAuthenticated(true);
    } catch (e) {
      alert(e);
    }
  }

  return (
    <div className="App container">
      <h1>Welcome to my app</h1>
      <Switch>
        <UnauthenticatedRoute
          path="/login"
          component={Login}
          appProps={{ isAuthenticated }}
        />
        <AuthenticatedRoute
          path="/todos"
          component={Todos}
          appProps={{ isAuthenticated }}
        />
        <Route component={NotFound} />
      </Switch>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

要使用此HOC,只需将其包裹在您的路线上即可.如果你的例子,它将是:

export default function AuthenticatedRoute({ component: C, appProps, ...rest }) {
  return (
    <Route
      {...rest}
      render={props =>
        appProps.isAuthenticated
          ? <C {...props} {...appProps} />
          : <Redirect
              to={`/login?redirect=${props.location.pathname}${props.location.search}`}
            />}
    />
  );
}
Run Code Online (Sandbox Code Playgroud)

我在这里详细分步教程中介绍了这个和其他一些主题 - http://serverless-stack.com/chapters/create-a-hoc-that-c​​hecks-auth.html

  • `<Route handler = {} />`在v1.0中已弃用,你应该使用`<Route component = {} />`. (7认同)
  • @karimelhelawy这是真的,因此您需要在服务器的API中强制执行身份验证. (4认同)

jac*_*cob 25

在React Router 4的文档中有(现在?)这样的例子 Redirect

import { Route, Redirect } from 'react-router'

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>
Run Code Online (Sandbox Code Playgroud)


gwe*_*all 5

react-router鼓励对路由器使用声明性方法,因此您应该使路由器尽可能愚蠢,并避免将路由逻辑放入组件中。

以下是如何做到这一点(假设您将loggedInprop 传递给它):

const DumbRouter = ({ loggedIn }) => (
  <Router history={history}>
    <Switch>
      {[
        !loggedIn && LoggedOutRoutes,
        loggedIn && LoggedInRouter,
        <Route component={404Route} />
      ]}
    </Switch>
  </Router>
);

const LoggedInRoutes = [
  <Route path="/" component={Profile} />
];

const LoggedOutRoutes = [
  <Route path="/" component={Login} />
];
Run Code Online (Sandbox Code Playgroud)