当前位置: 首页 > 面试题库 >

如何使用react-router处理身份验证?

石正奇
2023-03-14
问题内容

尝试进行某些路由需要身份验证。

我有这个:

    class App extends Component {
      render() {
        const menuClass = `${this.props.contentMenuClass} col-xs-12 col-md-9`;
        return (  
          <BrowserRouter history={browserHistory}>
            <div className="App">
              <Header properties={this.props} />
                <div className="container-fluid">
                  <div className="row">
                    <SideNav />
                    <div className={menuClass} id="mainContent">
                      <Switch>
                        {routes.map(prop =>
                            (
                              <Route
                                path={prop.path}
                                component={prop.component}
                                key={prop.id}
                                render={() => (
                                  !AuthenticationService.IsAutheenticated() ? 
                                    <Redirect to="/Login"/>
                                   : 
                                   <Route path={prop.path}
                                   component={prop.component}
                                   key={prop.id}/>

                                )}
                              />
                            ))}
                      </Switch>
                    </div>
                  </div>
                </div>
              {/* <Footer /> */}

            </div>

          </BrowserRouter>
        );
      }
    }

    const mapStateToProps = state => ({
      contentMenuClass: state.menu,
    });

    export default connect(mapStateToProps)(App);

注意:是的,身份验证服务可以正常工作。

对于每条路由,我都会检查用户是否已通过身份验证,如果没有通过身份验证,则要将他们重定向到登录页面,如果已通过身份验证,则它将以“ /”路由登陆到第一页。

我得到的是:

>     react-dom.development.js:14227 The above error occurred in the <Route>
> component:
>         in Route (created by App)
>         in Switch (created by App)
>         in div (created by App)
>         in div (created by App)
>         in div (created by App)
>         in div (created by App)
>         in Router (created by BrowserRouter)
>         in BrowserRouter (created by App)
>         in App (created by Connect(App))
>         in Connect(App)
>         in Provider

我在哪里做错了?


问题答案:

一个简单的解决方案是制作一个HOC包含所有受保护路线的(高阶组件)。

根据您的应用程序的嵌套方式,您可能需要利用本地redux状态。

工作示例:https :
//codesandbox.io/s/5m2690nn6n(使用本地状态)

路线/index.js

    import React from "react";
    import { BrowserRouter, Switch, Route } from "react-router-dom";
    import Home from "../components/Home";
    import Players from "../components/Players";
    import Schedule from "../components/Schedule";
    import RequireAuth from "../components/RequireAuth";

    export default () => (
      <BrowserRouter>
        <RequireAuth>
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/players" component={Players} />
            <Route path="/schedule" component={Schedule} />
          </Switch>
        </RequireAuth>
      </BrowserRouter>
    );

组件/RequireAuth.js

    import React, { Component, Fragment } from "react";
    import { withRouter } from "react-router-dom";
    import Login from "./Login";
    import Header from "./Header";

    class RequireAuth extends Component {
      state = { isAuthenticated: false };

      componentDidMount = () => {
        if (!this.state.isAuthenticated) {
          this.props.history.push("/");
        }
      };

      componentDidUpdate = (prevProps, prevState) => {
        if (
          this.props.location.pathname !== prevProps.location.pathname &&
          !this.state.isAuthenticated
        ) {
          this.props.history.push("/");
        }
      };

      isAuthed = () => this.setState({ isAuthenticated: true });

      unAuth = () => this.setState({ isAuthenticated: false });

      render = () =>
        !this.state.isAuthenticated ? (
          <Login isAuthed={this.isAuthed} />
        ) : (
          <Fragment>
            <Header unAuth={this.unAuth} />
            {this.props.children}
          </Fragment>
        );
    }

    export default withRouter(RequireAuth);

或者,您可以创建一个包含受保护路由的受保护组件,而不是包装路由。

工作示例:https :
//codesandbox.io/s/yqo75n896x(使用redux代替本地状态)。

路线/index.js

    import React from "react";
    import { BrowserRouter, Route, Switch } from "react-router-dom";
    import { createStore } from "redux";
    import { Provider } from "react-redux";
    import Home from "../components/Home";
    import Header from "../containers/Header";
    import Info from "../components/Info";
    import Sponsors from "../components/Sponsors";
    import Signin from "../containers/Signin";
    import RequireAuth from "../containers/RequireAuth";
    import rootReducer from "../reducers";

    const store = createStore(rootReducer);

    export default () => (
      <Provider store={store}>
        <BrowserRouter>
          <div>
            <Header />
            <Switch>
              <Route exact path="/" component={Home} />
              <Route path="/info" component={Info} />
              <Route path="/sponsors" component={Sponsors} />
              <Route path="/protected" component={RequireAuth} />
              <Route path="/signin" component={Signin} />
            </Switch>
          </div>
        </BrowserRouter>
      </Provider>
    );

容器/RequireAuth.js

    import React from "react";
    import { Route, Redirect } from "react-router-dom";
    import { connect } from "react-redux";
    import ShowPlayerRoster from "../components/ShowPlayerRoster";
    import ShowPlayerStats from "../components/ShowPlayerStats";
    import Schedule from "../components/Schedule";

    const RequireAuth = ({ match: { path }, isAuthenticated }) =>
      !isAuthenticated ? (
        <Redirect to="/signin" />
      ) : (
        <div>
          <Route exact path={`${path}/roster`} component={ShowPlayerRoster} />
          <Route path={`${path}/roster/:id`} component={ShowPlayerStats} />
          <Route path={`${path}/schedule`} component={Schedule} />
        </div>
      );

    export default connect(state => ({
      isAuthenticated: state.auth.isAuthenticated
    }))(RequireAuth);

您甚至可以通过创建包装函数来获得更多的模块化。您只需包装组件即可选择任何路线。

例如: <Route path="/blog" component={RequireAuth(Blog)} />



 类似资料:
  • 试图使某些路由需要身份验证。 我有这个: 注意:是的,身份验证服务正常工作。 对于每个路由,我检查用户是否经过身份验证,如果没有,那么我想将他们重定向到登录页面,如果他们是,那么它将在第一个页面上着陆,路由为"/"。 我得到的只是: 我哪里做错了?

  • 问题内容: 如何使用HtmlUnitDriver处理身份验证? 问题答案: 在Java中尝试这个似乎对我有用

  • 问题内容: 我正在尝试为我的支票写支票。但是该函数本身并未被调用。有人可以给我一些解决方案吗?我正在用ReactJs开发。 这是路线部分: 这是功能: 问题答案: 在,你可以利用来与生命周期方法一起更换功能存在于反应路由器V3。 查看此答案以获取更多详细信息: react-router v4中的onEnter prop 但是,由于您要做的只是在onEnter道具中进行身份验证,因此您可以轻松创建一

  • 我有一个快速服务器运行,以启用用户身份验证使用护照。我在运行快速URL时获取用户信息,但我无法使用axios从我的反应应用程序中获取用户对象。我的反应应用程序说网络错误。 我试着用 快速应用程序。js(以) 我的express应用程序在端口3000上运行,因此我可以在访问时看到用户对象http://localhost:3000/user 但是当我试图在我的反应应用程序中访问这个时,我收到了网络错误

  • 问题内容: C#中基于Selenium Webdriver的测试必须使用Windows身份验证登录。 我尝试了几种方法: 和 都不成功。我没有在本地系统上获得Windows身份验证对话框,因此无法查看源来确定如何使用Selenium By方法定位用户名和密码。 我相信Windows身份验证对话框是由浏览器提供的,但是我没有找到该对话框的任何来源。 使用Selenium(不是AutoIt或其他类似工

  • 我已尝试在URL中发送用户名和密码 我已尝试使用报警处理,但不起作用。 我尝试了中提供的解决方案-如何使用Java处理Selenium WebDriver弹出的身份验证,几乎所有的解决方案都不是AutoIT,但没有一个对我有效 我有一个Maven项目,我正在尝试从project.properties文件发送带有用户名和密码的url,看起来像这样- URL=https://username:pass