如何限制对反应路由器中路由的访问? [英] How to restrict access to routes in react-router?

查看:18
本文介绍了如何限制对反应路由器中路由的访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

<NotFoundRoute handler={NotFound} name="not-found"/><DefaultRoute handler={Login} name="login"/><Route handler={Todos} name="todos"/>{/* 我希望这个被限制 */}</路线>

解决方案

更新(2019 年 8 月 16 日)

在 react-router v4 和使用 React Hooks 这看起来有点不同.让我们从您的 App.js 开始.

导出默认函数 App() {const [isAuthenticated, userHasAuthenticated] = useState(false);useEffect(() => {负载();}, []);异步函数 onLoad() {尝试 {等待 Auth.currentSession();userHasAuthenticated(true);}赶上(e){警报(e);}}返回 (<div className="应用程序容器"><h1>欢迎使用我的应用</h1><开关><未认证路由路径=/登录"组件={登录}appProps={{ isAuthenticated }}/><认证路由路径=/待办事项"组件={Todos}appProps={{ isAuthenticated }}/><路由组件={NotFound}/></开关>

);}

我们正在使用 Auth 库来检查用户当前是否已通过身份验证.将其替换为您的身份验证检查功能.如果是,那么我们将 isAuthenticated 标志设置为 true.我们在应用程序首次加载时执行此操作.另外值得一提的是,您可能希望在运行身份验证检查时在您的应用程序上添加一个加载标志,这样您就不会在每次刷新页面时都刷新登录页面.

然后我们将标志传递给我们的路线.我们创建了两种类型的路由 AuthenticatedRouteUnauthenticatedRoute.

AuthenticatedRoute.js 看起来像这样.

导出默认函数AuthenticatedRoute({ component: C, appProps, ...rest }) {返回 (<路线{...休息}渲染={道具=>appProps.isAuthenticated?<C {...props} {...appProps}/>: <重定向to={`/login?redirect=${props.location.pathname}${props.location.search}`}/>}/>);}

它检查 isAuthenticated 是否设置为 true.如果是,那么它将呈现所需的组件.如果没有,那么它会重定向到登录页面.

另一方面,UnauthenticatedRoute.js 看起来像这样.

export default ({ component: C, appProps, ...rest }) =><路线{...休息}渲染={道具=>!appProps.isAuthenticated?<C {...props} {...appProps}/>: <重定向到="/"/>}/>;

在这种情况下,如果 isAuthenticated 设置为 false,它将呈现所需的组件.如果设置为 true,它会将您发送到主页.

您可以在我们的指南中找到详细版本 - https://serverless-stack.com/chapters/create-a-route-that-redirects.html.

旧版本

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

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

这是一个 HOC 示例,它会在继续之前检查用户是否已登录.如果用户未登录,那么它会将您重定向到登录页面.这个组件需要一个名为 isLoggedIn 的 prop,它基本上是一个标志,你的应用程序可以存储它来表示用户是否登录.

从'react'导入React;从反应路由器"导入 { withRouter };导出默认函数 requireAuth(Component) {类 AuthenticatedComponent 扩展 React.Component {componentWillMount() {this.checkAuth();}checkAuth() {如果(!this.props.isLoggedIn){const location = this.props.location;const 重定向 = location.pathname + location.search;this.props.router.push(`/login?redirect=${redirect}`);}}使成为() {返回 this.props.isLoggedIn?<组件{ ...this.props }/>: 空值;}}返回 withRouter(AuthenticatedComponent);}

要使用此 HOC,只需将其包裹在您的路线上.在您的示例中,它将是:

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

Does anyone know how to restrict access to particular routes in react-router? I want to check if the user is logged in before allowing access to a particular route. I thought it would be simple, but the docs aren't clear how to do it.

Is this something I should set up where I define my <Route> components, or should I be handling it inside my component handlers?

<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>

解决方案

Update (Aug 16, 2019)

In react-router v4 and using React Hooks this looks a little different. Let's start with your 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>
  );
}

We are using an Auth library to check if the user is currently authenticated. Replace this with your auth check function. If so then we set the isAuthenticated flag to true. We do this when our App first loads. Also worth mentioning, you might want to add a loading sign on your app while the auth check is being run, so you don't flash the login page every time you refresh the page.

Then we pass the flag to our routes. We create two type of routes AuthenticatedRoute and UnauthenticatedRoute.

The AuthenticatedRoute.js looks like this.

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}`}
            />}
    />
  );
}

It checks if isAuthenticated is set to true. If it is, then it'll render the desired component. If not, then it'll redirect to the login page.

The UnauthenticatedRoute.js on the other hand looks like this.

export default ({ component: C, appProps, ...rest }) =>
  <Route
    {...rest}
    render={props =>
      !appProps.isAuthenticated
        ? <C {...props} {...appProps} />
        : <Redirect to="/" />}
  />;

In this case, if the isAuthenticated is set to false, it'll render the desired component. And if it is set to true, it'll send you to the homepage.

You can find detailed versions of this on our guide - https://serverless-stack.com/chapters/create-a-route-that-redirects.html.

Older version

The accepted answer is correct but Mixins are considered to be harmful (https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html) by the React team.

If somebody comes across this question and is looking for the recommended way to do this, I'd suggest using Higher Order Components instead of Mixins.

Here is an example of a HOC that'll check if the user is logged in before proceeding. And if the user is not logged in, then it'll redirect you to the login page. This component takes a prop called isLoggedIn, that is basically a flag that your application can store to denote if the user is logged in.

import React from 'react';
import { withRouter } from 'react-router';

export default function requireAuth(Component) {

  class AuthenticatedComponent extends React.Component {

    componentWillMount() {
      this.checkAuth();
    }

    checkAuth() {
      if ( ! this.props.isLoggedIn) {
        const location = this.props.location;
        const redirect = location.pathname + location.search;

        this.props.router.push(`/login?redirect=${redirect}`);
      }
    }

    render() {
      return this.props.isLoggedIn
        ? <Component { ...this.props } />
        : null;
    }

  }

  return withRouter(AuthenticatedComponent);
}

And to use this HOC, just wrap it around your routes. In case of your example, it would be:

<Route handler={requireAuth(Todos)} name="todos"/>

I cover this and a few other topics in a detailed step-by-step tutorial here - https://serverless-stack.com/chapters/create-a-hoc-that-checks-auth.html

这篇关于如何限制对反应路由器中路由的访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆