Apprends à supprimer proprement le cookie de session à la déconnexion et à gérer la redirection pour une meilleure UX avec React Router 7.
avec React Router 7
Posez vos questions 24/7 à notre IA experte en React Router 7
Validez vos acquis avec des quiz personnalisés et un feedback instantané
Clique‐tu sur « Logout », tu es toujours renvoyé sur la page d’accueil. Ce choix paraît anodin mais pose deux soucis :
document.cookie
) avant de se déconnecter,
le backend ne le reconnaît plus… mais le cookie reste stocké. Mieux vaut le supprimer
pour repartir d’une session propre./users
).
Forcer un détour par la home rend la navigation inutilement longue.Nous allons :
logout();
redirectTo
.logout()
côté serveur1import { createCookieSessionStorage, redirect } from "react-router";23const { getSession, destroySession } = createCookieSessionStorage({4cookie: { name: "__session" } // config réduite pour l'exemple5});67export async function logout({8request,9redirectTo = "/"10}: { request: Request; redirectTo?: string }) {11const session = await getSession(request.headers.get("Cookie"));12return redirect(redirectTo, {13headers: { "Set-Cookie": await destroySession(session) } // 🍪 supprimé14});15}
destroySession(session)
renvoie un header Set-Cookie
qui vide le cookie côté
navigateur./logout
L’endpoint ne fait désormais qu’appeler le helper et transmettre le paramètre d’URL éventuel :
1import { logout } from "~/server/sessions.server";23export async function action({ request }: ActionFunctionArgs) {4const url = new URL(request.url);5const redirectTo = url.searchParams.get("redirectTo") || "/";6return logout({ request, redirectTo });7}
Pour remplir automatiquement redirectTo
avec la page en cours, on s’appuie
sur le hook useLocation
.
1import { Form, useLocation, href } from "react-router";23export function Layout({ children }: { children: React.ReactNode }) {4// …5const { pathname } = useLocation();67return (8<Form9method="POST"10action={`${href("/logout")}?redirectTo=${pathname}`} // 🏷️ param dynamique11>12<button className="cursor-pointer">Logout</button>13</Form>14);15}
Avantages :
/users
, tu reviens sur /users
(version « déconnecté »)./profile
) tu reçois une double redirection
/logout → /profile → /login
.
C’est volontaire : la deuxième vérification assure qu’aucune page
sensible n’est rendue sans session valide.logout()
depuis requireUser()
Lorsque le cookie est corrompu, on veut supprimer la session avant de
rediriger vers /login
.
On déplace donc la logique dans le garde d’authentification :
1export async function requireUser({ request }: { request: Request }) {2const session = await getSession(request.headers.get("Cookie"));3const id = session.get("userId");45if (!id) {6const url = new URL(request.url);7const redirectTo = `/login?redirectTo=${url.pathname}`;8throw await logout({ request, redirectTo }); // 🔥 cookie détruit9}10return id;11}
Un cookie falsifié est donc effacé avant même que la page protégée ne charge.
Avant | Après |
---|---|
Route /logout installe un cookie vide et | Le helper logout() vide le cookie une seule fois |
redirige systématiquement vers / | & redirige vers le chemin passé en paramètre |
Les pages protégées gardent un cookie invalide | Cookie effacé dès qu’il est incohérent |
Déconnexion casse le flow « switcher de compte » | L’utilisateur revient là où il était |
logout()
/logout
et dans requireUser
redirectTo
à l’URL du formulaire via useLocation
Quelle est la principale différence entre les composants client et serveur dans React ?
Quelle technique est recommandée pour éviter les rendus inutiles dans React ?
Quel hook permet de gérer les effets de bord dans un composant React ?
Comment implémenter la gestion des erreurs pour les requêtes API dans React ?
Quelle est la meilleure pratique pour déployer une application React en production ?