Architecture

Flux d'authentification JWT

Fonctionnement de l'authentification par JWT dans TrickSpin.

Flux d'authentification JWT

TrickSpin utilise LexikJWTAuthenticationBundle avec une stratégie de stockage en HttpOnly cookies (pas de localStorage).

Connexion

Client (Nuxt)          Symfony
     |                    |
     |-- POST /api/login ->|
     |                    |-- Vérifie les credentials
     |                    |-- Génère le JWT (TTL : 24 h)
     |                    |-- Génère le refresh token (TTL : 30 j, stocké en BDD)
     |<- Set-Cookie: jwt_hp, jwt_s, refresh_token --|
     |                    |

Le JWT est splitté en deux cookies (jwt_hp et jwt_s) via split: true de LexikJWT. Le refresh token est un cookie HttpOnly supplémentaire émis par JwtAuthenticationSubscriber.

Requêtes authentifiées

Client (Nuxt)          Symfony
     |                    |
     |-- GET /api/... --->|   (cookies envoyés automatiquement)
     |                    |-- Extrait le JWT depuis jwt_hp + jwt_s
     |                    |-- Valide le token
     |<-- 200 / données --|
     |                    |

Renouvellement automatique (refresh)

Quand le JWT expire (après 24 h), le front tente un refresh silencieux avant de déconnecter :

Client (Nuxt)          Symfony
     |                    |
     |-- POST /api/token/refresh -->|  (refresh_token cookie envoyé)
     |                    |-- Valide le refresh token en BDD
     |                    |-- Supprime l'ancien refresh token (rotation)
     |                    |-- Génère un nouveau JWT
     |                    |-- Génère un nouveau refresh token
     |<- Set-Cookie: jwt_hp, jwt_s, refresh_token --|
     |                    |

Ce mécanisme est déclenché dans :

  • plugins/auth.client.ts - garde de navigation (router.beforeEach)
  • pages/menu/index.vue - vérification au montage de la page

Déconnexion

Client (Nuxt)          Symfony
     |                    |
     |-- POST /api/users/logout -->|
     |                    |-- Supprime le refresh token en BDD
     |                    |-- Clear-Cookie: jwt_hp, jwt_s, refresh_token
     |<-- 200 OK ---------|
     |                    |

Protection contre le brute force

Les tentatives de connexion sont limitées via symfony/rate-limiter : 5 tentatives maximum sur une fenêtre de 15 minutes par adresse IP.

Durées de vie configurables

CookieTTLHttpOnlyRôle
jwt_hp24 hNonHeader + payload du JWT (lecture côté client)
jwt_s24 hOuiSignature du JWT
refresh_token30 jOuiRenouvellement du JWT sans re-login

Les durées sont configurées via :

  • lexik_jwt_authentication.yamltoken_ttl
  • Variable d'environnement REFRESH_TOKEN_TTL (en secondes)