代码之家  ›  专栏  ›  技术社区  ›  ThunD3eR

如何使用react路由器处理身份验证?

  •  0
  • ThunD3eR  · 技术社区  · 7 年前

    我有这个:

    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服务正常工作。

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

    我得到的只是:

    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
    

    2 回复  |  直到 7 年前
        1
  •  3
  •   Matt Carlotta    7 年前

    一个简单的解决办法就是 HOC (高阶组件)封装所有受保护的路由。

    redux 州。

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

    路由/索引.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 雷杜 而不是地方政府)。

    路由/索引.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);
    

    setup .

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

        2
  •  0
  •   neaumusic    7 年前

    Autheenticated 错了。

    另外,这是一个假设,因为您只提供了堆栈跟踪,而没有提供 above error ,也就是说 AuthenticationService.IsAutheenticated 不是函数。