javascript - with - secured route react router




Comment restreindre l'accès aux routes dans react-router? (4)

Est-ce que quelqu'un sait comment restreindre l'accès à certaines routes dans react-router? Je souhaite vérifier si l'utilisateur est connecté avant de permettre l'accès à un itinéraire particulier. Je pensais que ce serait simple, mais les documents ne savent pas comment le faire.

Est-ce quelque chose que je devrais configurer pour définir mes composants <Route> , ou devrais-je le manipuler dans mes gestionnaires de composants?

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

Mise à jour (16 août 2019)

Dans react-router v4 et en utilisant React Hooks, cela semble un peu différent. Commençons par votre 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>
  );
}

Nous utilisons une bibliothèque d'authentification pour vérifier si l'utilisateur est actuellement authentifié. Remplacez-le par votre fonction de vérification d'authentification. Si tel est le cas, nous définissons l'indicateur isAuthenticated sur true . Nous le faisons lors du premier chargement de notre application. Il convient également de mentionner que vous voudrez peut-être ajouter un signe de chargement sur votre application lors de l'exécution de la vérification automatique, afin de ne pas flasher la page de connexion à chaque fois que vous actualisez la page.

Ensuite, nous passons le drapeau à nos itinéraires. Nous créons deux types de routes AuthenticatedRoute et UnauthenticatedRoute .

Le AuthenticatedRoute.js ressemble à ceci.

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

Il vérifie si isAuthenticated est défini sur true . Si c'est le cas, le composant souhaité sera rendu. Si non, alors il va rediriger vers la page de connexion.

Le UnauthenticatedRoute.js ressemble à cela.

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

Dans ce cas, si isAuthenticated est défini sur false , le composant souhaité sera rendu. Et s'il est défini sur true, il vous enverra à la page d'accueil.

Vous pouvez trouver des versions détaillées de ceci dans notre guide - https://serverless-stack.com/chapters/create-a-route-that-redirects.html .

Ancienne version

La réponse acceptée est correcte mais les Mixins sont considérés comme nocifs ( https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html ) par l'équipe de React.

Si quelqu'un tombe sur cette question et cherche la manière recommandée de le faire, je suggérerais d'utiliser des composants d'ordre supérieur au lieu de Mixins.

Voici un exemple de HOC qui vérifiera si l'utilisateur est connecté avant de continuer. Et si l'utilisateur n'est pas connecté, il vous redirigera vers la page de connexion. Ce composant isLoggedIn un accessoire appelé isLoggedIn . Il s'agit en gros d'un indicateur que votre application peut stocker pour indiquer si l'utilisateur est connecté.

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

Et pour utiliser ce COH, enroulez-le simplement autour de vos itinéraires. Dans le cas de votre exemple, ce serait:

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

Je couvre ceci et quelques autres sujets dans un tutoriel détaillé étape par étape ici - https://serverless-stack.com/chapters/create-a-route-that-redirects.html


Il existe (maintenant?) Un exemple dans les documents de React Router 4 pour la Redirect

import { Route, Redirect } from 'react-router'

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

généralement, un utilisateur connecté se voit attribuer un jeton, qu'il utilise pour toute communication avec le serveur. En général, nous définissons une page racine et les choses se construisent en haut de cette page. cette page racine fait pour vous la localisation, l'authentification et d'autres configurations.

voici un exemple

Routes = (
    <Route path="/" handler={Root}>
        <Route name="login" handler={Login} />
        <Route name="forget" handler={ForgetPassword} />
        <Route handler={Main} >
            <Route name="overview" handler={Overview} />
            <Route name="profile" handler={Profile} />
            <DefaultRoute handler={Overview} />
        </Route>
        <DefaultRoute handler={Login} />
        <NotFoundRoute handler={NotFound} />
    </Route>
);

sur votre page racine, vérifiez que le jeton a la valeur null ou authentifiez-le avec le serveur pour voir si l'utilisateur est connecté.

J'espère que cela t'aides :)


react-router encourage une approche déclarative de votre routeur. Vous devez rendre votre routeur aussi bête que possible et éviter de placer votre logique de routage dans vos composants.

Voici comment vous pouvez le faire (en supposant que vous passiez le prop loggedIn ):

const DumbRouter = ({ loggedIn }) => (
  <Router history={history}>
    <Switch>
      {[
        !loggedIn && LoggedOutRoutes,
        loggedIn && LoggedInRouter,
        <Route component={404Route} />
      ]}
    </Switch>
  </Router>
);

const LoggedInRoutes = [
  <Route path="/" component={Profile} />
];

const LoggedOutRoutes = [
  <Route path="/" component={Login} />
];




react-router