Comment gérer l'authentification avec routeur réagir?

voix
0

Essayer de faire certaines routes nécessitent une authentification.

J'ai ceci:

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

Remarque: Oui, le service fonctionne auth comme il se doit.

Pour chaque route que je vérifie si l'utilisateur est authentifié, sinon je veux les rediriger vers la page de connexion, si elles sont alors il atterrira sur la première page avec la route de « / ».

Tout ce que je reçois est:

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

Où suis-je en train de faire ce mal?

Créé 07/11/2018 à 20:22
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
2

Une solution simple serait de faire un HOC(ordre élevé des composants) qui enveloppe tous les itinéraires protégés.

Selon la façon dont votre application est imbriqué, vous pouvez utiliser l' état ou local reduxétat.

Exemple de travail: https://codesandbox.io/s/5m2690nn6n (celui - ci utilise l' état local)

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

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

Ou, au lieu d'itinéraires d'emballage, vous pouvez créer un composant protégé qui abrite les routes protégées.

Exemple de travail: https://codesandbox.io/s/yqo75n896x (utilise au reduxlieu de l' état local).

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

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

Vous pouvez même obtenir plus modulaire en créant une fonction d'emballage. Vous seriez en mesure de choisir une route en enroulant simplement sur le composant. Je n'ai pas un exemple de codebox, mais il serait similaire à cette configuration .

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

Créé 07/11/2018 à 20:36
source utilisateur

voix
0

Vous orthographié Autheenticatedmal.

De plus, ceci est une hypothèse parce que vous ne fourni la trace de la pile et non la above error, qui dit sans doute AuthenticationService.IsAutheenticatedest pas une fonction.

Créé 07/11/2018 à 20:30
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more