Une application Angular, une API Spring Boot, un serveur d'identité. Reste une question qui a l'air d'un détail d'implémentation, et qui décide de tout ce qui suit : le navigateur reçoit-il le jeton d'accès, ou seulement un cookie de session ?
Deux réponses, également défendables
Le BFF. Un service intermédiaire détient le jeton. Le navigateur ne reçoit qu'un cookie de session httpOnly, que le JavaScript de la page ne peut pas lire. C'est la direction que recommandent aujourd'hui les bonnes pratiques pour les applications navigateur.
La SPA cliente publique. L'application obtient elle-même son jeton par le flux d'autorisation avec PKCE, le garde en mémoire, et l'envoie à l'API. Un service de moins à écrire, à déployer et à surveiller. Aucune session à tenir. Le jeton disparaît à la fermeture de l'onglet.
Ce que le BFF achète vraiment
Une faille XSS ne vole rien, puisqu'il n'y a rien à voler. Le jeton, sa durée de vie, ses portées et son renouvellement restent hors de portée du navigateur — donc hors de portée d'un script injecté, d'une dépendance compromise, ou d'une balise de mesure d'audience posée par quelqu'un d'autre que vous.
Ce qu'il coûte, et qu'on annonce rarement
- Un service de plus. À écrire, à déployer, à surveiller, à mettre à jour.
- De l'état. Une session à tenir quelque part — mémoire, cache, base — là où la SPA n'avait rien à tenir.
- Le CSRF revient. Il avait disparu avec le cookie ; il revient avec lui.
- Un saut de plus sur chaque appel, et un point de panne de plus sur le chemin.
Ce que les deux camps oublient
C'est le point qui manque le plus souvent au débat, et c'est le plus important. Le cookie httpOnly empêche l'exfiltration, pas l'abus.
Un script injecté dans la page ne lit pas le cookie — mais il n'en a pas besoin. Il envoie ses requêtes depuis la page, et le navigateur y joint le cookie tout seul.
Le BFF réduit donc la fenêtre plutôt qu'il ne ferme la porte : un jeton volé sert ailleurs et longtemps, une session détournée ne sert que là, et que tant que l'onglet vit. C'est un vrai gain, et il ne dispense pas de l'étape qui compte — ne pas avoir de XSS.
Le critère
« Recommandé » n'est pas « toujours justifié ». La question à poser n'est pas quel motif est le mieux vu cette année, mais : que vaut ce que le jeton ouvre ?
Un outil interne à trente personnes, dont le pire scénario est qu'un employé voie un tableau de bord qui ne le concerne pas : le coût d'exploitation du BFF dépasse probablement le gain.
Une application qui déclenche des paiements, corrige des prix ou ouvre des caisses : le calcul s'inverse, et il s'inverse d'un coup.
Une seconde question, moins posée : qui exploitera ce service dans deux ans ? Un BFF que plus personne ne met à jour n'est pas une protection — c'est un serveur exposé de plus.
Ce que j'en retiens
Il n'existe pas de réponse indépendante de ce qu'on protège. Il y a une bonne pratique, un coût d'exploitation, et une valeur en face. Le seul mauvais choix est celui qu'on fait sans avoir posé les trois.