Contactez-nous

Routes protégées (Authentification)

Apprenez à sécuriser des sections de votre application React en créant des routes protégées qui nécessitent une authentification, en utilisant React Router et la gestion d'état.

Sécuriser l'accès : La nécessité des routes protégées

La plupart des applications web contiennent des sections qui ne devraient être accessibles qu'aux utilisateurs authentifiés. Par exemple, un tableau de bord personnel, une page de profil, les paramètres du compte, ou des fonctionnalités spécifiques réservées aux administrateurs. Il est crucial d'empêcher les utilisateurs non connectés (ou non autorisés) d'accéder à ces zones.

React Router, bien qu'il ne gère pas l'authentification elle-même (qui relève de la gestion d'état et de la communication avec un backend), fournit les mécanismes nécessaires pour implémenter la logique de protection de ces routes. L'idée principale est de vérifier l'état d'authentification de l'utilisateur avant de rendre le composant associé à une route protégée. Si l'utilisateur n'est pas authentifié, il est généralement redirigé vers une page de connexion.

Le pattern du composant wrapper `RequireAuth`

Une approche courante et propre pour implémenter des routes protégées consiste à créer un composant wrapper (souvent nommé `RequireAuth`, `ProtectedRoute`, ou `PrivateRoute`). Ce composant a pour responsabilité de :

1. Vérifier l'état d'authentification de l'utilisateur (via un contexte, Redux, Zustand, etc.).

2. Si l'utilisateur est authentifié, rendre le composant enfant demandé (la page protégée elle-même).

3. Si l'utilisateur n'est pas authentifié, le rediriger vers la page de connexion, idéalement en mémorisant l'URL à laquelle il tentait d'accéder initialement pour pouvoir l'y renvoyer après une connexion réussie.

Ce composant wrapper utilise le composant `` que nous avons vu précédemment pour effectuer la redirection.

Pour obtenir l'état d'authentification, on utilise généralement un hook personnalisé (par exemple `useAuth`) qui puise dans un système de gestion d'état global (comme le Context API de React). Nous aurons aussi besoin du hook `useLocation` pour récupérer l'URL actuelle avant la redirection.

Implémentation d'un composant `RequireAuth`

Voyons à quoi pourrait ressembler un composant `RequireAuth` typique. Supposons que nous ayons un hook `useAuth()` qui retourne un objet contenant l'état de l'utilisateur (par exemple, `{ utilisateur: null }` si non connecté, `{ utilisateur: { id: 1, name: '...' } }` si connecté).

// components/RequireAuth.js
import React from 'react';
import { useLocation, Navigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext'; // Assurez-vous que le chemin est correct

function RequireAuth({ children }) {
  const { utilisateur } = useAuth(); // Récupère l'état d'authentification
  const location = useLocation(); // Récupère l'objet location actuel

  if (!utilisateur) {
    // Utilisateur non authentifié
    // Redirection vers la page de connexion ('/login')
    // 'replace' évite d'ajouter la page protégée à l'historique avant la connexion
    // 'state={{ from: location }}' passe l'URL d'origine à la page de login
    return ;
  }

  // Utilisateur authentifié, on rend le composant enfant demandé (la page protégée)
  return children;
}

export default RequireAuth;

Points importants :

  • `useAuth()` : C'est ici que vous connectez votre logique d'authentification.
  • `useLocation()` : Permet d'obtenir l'objet `location` actuel, qui contient notamment le `pathname` (l'URL à laquelle l'utilisateur tentait d'accéder).
  • `!utilisateur` : La condition qui détermine si l'utilisateur est connecté ou non. Adaptez-la selon la structure de votre état d'authentification.
  • `` : La redirection. `to="/login"` est la destination. `state={{ from: location }}` passe l'objet `location` d'origine à la page de connexion. `replace` est crucial pour une bonne expérience utilisateur (pas de retour possible à la page protégée non autorisée).
  • `return children;` : Si l'utilisateur est authentifié, le composant wrapper rend simplement ses enfants, qui correspondent au composant de la page protégée.

Utilisation dans la configuration des routes

Une fois le composant `RequireAuth` créé, il suffit de l'utiliser pour envelopper l'élément (`element`) des routes que vous souhaitez protéger dans votre configuration ``.

// Dans App.js ou votre fichier de configuration des routes
import React from 'react';
import {
  BrowserRouter,
  Routes,
  Route,
} from 'react-router-dom';

// ... autres imports
import RequireAuth from './components/RequireAuth';
import PageLogin from './pages/PageLogin';
import PageTableauDeBord from './pages/PageTableauDeBord';
import PageProfil from './pages/PageProfil';
import PageAccueil from './pages/PageAccueil';

function App() {
  return (
    // Assurez-vous que AuthProvider englobe cette partie si vous utilisez Context
    
      
        {/* Routes publiques */}
        } />
        } />

        {/* Routes protégées */}
        
              
            
          }
        />
        
              
            
          }
        />
        
        {/* Routes imbriquées protégées (exemple) */}
        
              
             
          }
        >
          } />
          } />
        

        {/* ... autres routes (ex: 404) */}
      
    
  );
}

export default App;

Avec cette configuration, si un utilisateur non connecté tente d'accéder à `/dashboard` ou `/profil`, le composant `RequireAuth` interceptera le rendu et le redirigera vers `/login`.

Gérer la redirection après connexion

La dernière pièce du puzzle est de s'assurer que, une fois la connexion réussie sur la page `/login`, l'utilisateur est redirigé vers la page qu'il tentait initialement d'atteindre.

La page de connexion (`PageLogin` dans notre exemple) peut accéder à l'information passée dans `state` via le hook `useLocation`. Après une connexion réussie, elle peut utiliser `useNavigate` pour rediriger l'utilisateur soit vers la page d'origine (`location.state?.from?.pathname`), soit vers une page par défaut (comme `/dashboard`) si aucune page d'origine n'a été spécifiée.

// pages/PageLogin.js
import React from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';

function PageLogin() {
  const navigate = useNavigate();
  const location = useLocation();
  const { login } = useAuth(); // Fonction pour déclencher la connexion

  // Détermine où rediriger après connexion : l'URL d'origine ou le dashboard par défaut
  const from = location.state?.from?.pathname || "/dashboard";

  const handleLogin = (/*...*/) => {
    // ... logique de connexion (appel API, etc.) ...
    login(/* userData */); // Mettre à jour l'état d'authentification
    
    // Rediriger vers la page d'origine ou la page par défaut
    navigate(from, { replace: true }); 
  };

  return (
    

Connexion

Vous devez être connecté pour accéder à cette page.

{/* Votre formulaire de connexion ici */}
); } export default PageLogin;

En combinant le composant `RequireAuth`, la gestion de l'état d'authentification, et la redirection intelligente après connexion, vous pouvez mettre en place un système robuste et sécurisé pour protéger les sections de votre application React.