如何使用react-router处理身份验证? [英] How to handle Authentication with react-router?

查看:148
本文介绍了如何使用react-router处理身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Trying to make certain routes require Authentication.

我有这个:

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

注意:是的,auth服务可以正常工作。

Note: Yes the auth service works as it should.

对于我检查用户是否经过身份验证的每条路由,如果没有,那么我想将它们重定向到登录页面,如果它们是,那么它将落在第一个页面的路径为/。

For every route I am checking if the user is authenticated, if not then I want to redirect them to the login page, if they are then it will land on the first page with the route of "/".

我得到的只是:


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 (高阶组件)包装所有受保护的路由。

A simple solution would be to make a HOC (High Order Component) that wraps all protected routes.

根据您的应用程序的嵌套方式,您可能希望使用本地州或 redux 州。

Depending upon how nested your app is, you may want to utilize local state or redux state.

工作示例: https://codesandbox.io/s/5m2690nn6n (这使用当地州)

Working example: https://codesandbox.io/s/5m2690nn6n (this uses local state)

路线/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>
);

components / 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);






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


Or, instead of wrapping routes, you can create a protected component that houses protected routes.

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

Working example: https://codesandbox.io/s/yqo75n896x (uses redux instead of local state).

routes / 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>
);

containers / 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)} />

这篇关于如何使用react-router处理身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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