Bonjour ! Dans la leçon précédente, vous avez brillamment mis en œuvre un backend Spring Boot complet, incluant la sécurité avec JWT et la documentation via OpenAPI. Vous disposez désormais d'une API robuste, prête à être consommée.
Aujourd'hui, nous allons construire le pont entre ce backend et le monde de l'utilisateur. L'objectif est de connecter un frontend React/Next.js à votre backend, en gérant de manière professionnelle l'authentification JWT. Votre expérience avec React est un atout majeur ; nous nous concentrerons donc sur les stratégies d'intégration, la communication API et, surtout, la gestion sécurisée du token côté client.
À la fin de cette leçon, vous saurez non seulement comment faire communiquer un client React avec une API Spring Boot, mais aussi comment implémenter une stratégie d'authentification qui résiste aux vulnérabilités courantes du web, une compétence essentielle pour tout développeur full-stack moderne.
1. Le Flux d'Authentification : Vue d'Ensemble
Avant de coder, visualisons le processus. Une fois qu'un utilisateur s'authentifie, le backend lui fournit un "laissez-passer" : le JWT. Le frontend doit alors stocker ce jeton et le présenter à chaque fois qu'il souhaite accéder à une ressource protégée.

Pour que ce flux fonctionne entre deux applications distinctes (notre backend sur le port 8080 et notre frontend Next.js sur le port 3000), un mécanisme est indispensable : le CORS (Cross-Origin Resource Sharing).
Votre backend Spring Boot doit explicitement autoriser les requêtes provenant de l'origine de votre frontend. Sans cela, le navigateur bloquera toutes les tentatives de fetch pour des raisons de sécurité. La configuration se fait généralement dans votre classe SecurityConfig en Spring, en autorisant l'URL de votre client (http://localhost:3000).
2. Une Première Approche Pratique : Stocker le JWT dans le localStorage
La manière la plus directe de gérer le JWT côté client est de le stocker dans le localStorage du navigateur. C'est une approche que vous rencontrerez souvent dans des tutoriels, car elle est simple à mettre en œuvre.
La vidéo suivante montre un exemple complet de connexion entre un backend Spring Boot et un frontend Next.js, en utilisant justement cette méthode. Nous allons nous concentrer sur la partie frontend.
Full Stack Spring Boot + NextJS JWT Authentication Tutorial
La vidéo "Full Stack Spring Boot + NextJS JWT Authentication Tutorial" de Full Stack Book, bien qu'en anglais, illustre parfaitement la logique de base côté frontend. Observez comment les composants React sont structurés pour gérer la connexion et l'affichage des données.
Regardez la section sur le code du frontend Next.js (de 23:39 à 27:10). Concentrez-vous sur les points suivants : La création des formulaires de connexion (signin) et d'inscription (signup). L'utilisation de fetch pour appeler les endpoints de votre API Spring Boot. La gestion de la réponse : en cas de succès, le token JWT est récupéré. Le stockage du token avec localStorage.setItem('token', ...). La redirection de l'utilisateur vers une page protégée.
Cette méthode est fonctionnelle et constitue une bonne base de départ. Cependant, pour un projet de calibre professionnel, elle présente une faille de sécurité majeure.
3. La Vulnérabilité du localStorage et la Solution Professionnelle
Le localStorage est un simple espace de stockage clé-valeur accessible par n'importe quel script JavaScript exécuté sur votre page. Cela le rend vulnérable aux attaques de type Cross-Site Scripting (XSS). Si un attaquant parvient à injecter un script malveillant sur votre site (via un commentaire, un champ de formulaire mal validé, etc.), ce script peut lire l'intégralité de votre localStorage et voler le JWT de l'utilisateur.
Pour construire des applications véritablement sécurisées, nous devons adopter une stratégie plus sophistiquée. L'article suivant, bien que s'appuyant sur des exemples Node.js, explique brillamment les concepts de sécurité côté client qui sont universels.
Sécuriser une API REST (3/3) : gestion du JWT coté client
L'article "Sécuriser une API REST (3/3) : gestion du JWT coté client" de Code Heroes est une lecture fondamentale. Il analyse les faiblesses des approches courantes et présente une solution robuste.
Lisez attentivement les sections "Erreur n°1 : Stockage des tokens dans le « localStorage »" et "Erreur n°2 : Stockage des tokens dans les cookies". L'objectif est de bien comprendre : Comment une attaque XSS peut voler un token depuis le localStorage. Pourquoi le stockage simple dans des cookies, bien que protégeant de XSS (avec l'attribut HttpOnly), introduit un autre risque : la faille CSRF (Cross-Site Request Forgery).
La Stratégie Hybride : "Double Submit Cookie"
Comme l'explique l'article, la solution la plus robuste consiste à combiner les cookies et le localStorage pour tirer parti des forces de chacun. Cette technique est souvent appelée "Double Submit Cookie Pattern".
Voici le déroulement :
-
Lors de la connexion (Login) :
- Backend :
- Génère le JWT et le place dans un cookie avec les attributs
HttpOnlyetSecure.HttpOnly: Rend le cookie inaccessible au code JavaScript, ce qui bloque les attaques XSS.Secure: Assure que le cookie n'est envoyé que sur des connexions HTTPS.
- Génère un token anti-CSRF (une chaîne de caractères aléatoire et unique). Il l'inclut dans le payload du JWT ET le renvoie dans le corps de la réponse JSON.
- Génère le JWT et le place dans un cookie avec les attributs
- Frontend :
- Le navigateur reçoit la réponse et stocke automatiquement le cookie
HttpOnlycontenant le JWT. - Votre code React/Next.js récupère le token anti-CSRF du corps de la réponse JSON et le stocke dans le
localStorage.
- Le navigateur reçoit la réponse et stocke automatiquement le cookie
- Backend :
-
Pour chaque requête ultérieure vers un endpoint protégé :
- Frontend :
- Le navigateur joint automatiquement le cookie
HttpOnly(contenant le JWT) à la requête. - Votre code React/Next.js doit lire le token anti-CSRF depuis le
localStorageet l'ajouter manuellement dans un en-tête HTTP personnalisé (par ex:X-XSRF-TOKEN).
- Le navigateur joint automatiquement le cookie
- Backend :
- Reçoit la requête.
- Vérifie la validité du JWT contenu dans le cookie.
- Extrait le token anti-CSRF du payload du JWT.
- Extrait le token anti-CSRF de l'en-tête
X-XSRF-TOKEN. - Compare les deux tokens anti-CSRF. S'ils correspondent, la requête est légitime.
- Frontend :
Pourquoi est-ce si sécurisé ?
- Contre XSS : L'attaquant ne peut pas voler le JWT, car il est dans un cookie
HttpOnly. - Contre CSRF : Un site malveillant peut forcer le navigateur de la victime à envoyer une requête avec le cookie JWT, mais il ne peut pas lire le
localStoragede votre site (à cause de la Same-Origin Policy). Il ne peut donc pas fournir l'en-têteX-XSRF-TOKENcorrect. Le backend détectera l'incohérence et rejettera la requête.
4. Mise en Pratique du Flux Sécurisé
L'implémentation de ce flux est plus complexe que la simple utilisation du localStorage, mais elle est la marque d'une application professionnelle. La logique est parfaitement décrite dans l'article de Code Heroes.
Sécuriser une API REST (3/3) : gestion du JWT coté client
Revenons à l'article de Code Heroes pour voir comment ce flux est implémenté.
Étudiez la section "FUUUUSION… HA !" qui détaille le code pour l'approche hybride. Côté serveur (à adapter pour votre backend Spring Boot) : Lors du login, en plus de générer le JWT, créez un token CSRF. Placez le JWT dans un cookie HttpOnly. Renvoyez une réponse JSON contenant le token CSRF. Côté client (logique pour votre frontend Next.js) : Après le login, stockez le token CSRF reçu dans le localStorage. Pour les requêtes authentifiées, créez un intercepteur de requêtes (avec axios par exemple) qui ajoute automatiquement l'en-tête X-XSRF-TOKEN en le lisant depuis le localStorage. Côté serveur (middleware/filtre de sécurité) : Vérifiez la présence et la correspondance entre le token CSRF du header et celui contenu dans le payload du JWT.
L'adaptation de ces concepts à votre stack (Spring Boot et Next.js) est un excellent exercice qui concrétise la théorie en une compétence pratique et très recherchée.
Conclusion
Aujourd'hui, vous avez connecté votre backend Spring Boot à un client Next.js, mais plus important encore, vous avez exploré en profondeur la gestion de l'authentification côté client.
Points clés à retenir :
- Le flux JWT de base : Un client s'authentifie, reçoit un token, et le présente pour accéder à des ressources. Le CORS est un prérequis pour la communication cross-origine.
- La faiblesse du
localStorage: Sa simplicité a un coût, la vulnérabilité aux attaques XSS. Il ne faut pas y stocker d'informations sensibles comme un JWT. - La solution professionnelle "Double Submit Cookie" : En combinant un cookie
HttpOnlypour le JWT et un token anti-CSRF transmis via le corps de la réponse et un en-tête, vous vous protégez à la fois contre les attaques XSS et CSRF. C'est le standard à viser pour des applications sécurisées.
Cette leçon vous a donné les clés pour non seulement construire une fonctionnalité, mais pour la construire correctement et de manière sécurisée.
Prochaine étape :
Maintenant que notre application full-stack est fonctionnelle et sécurisée, il est temps de la préparer pour le monde réel. Dans la prochaine leçon, "Déployer l'application full-stack complète via le pipeline CI/CD sur une plateforme cloud", nous verrons comment empaqueter notre backend et notre frontend, automatiser le processus de déploiement et les mettre en ligne.