Aller au contenu principal

Flow d'Authentification

Ce fichier documente comment fonctionne l'authentification sur StageConnect, basé sur le code réel du backend.

Vue d'Ensemble

Le système d'authentification utilise :

  • JWT pour les tokens d'accès
  • Supabase comme provider d'authentification
  • Redis pour le cache utilisateur (optionnel)
  • API REST pour les opérations auth

Structure des Tokens

Access Token

{
"sub": "user_id_123",
"email": "user@example.com",
"user_type": "STUDENT",
"school_id": "school_456",
"exp": 1740000000,
"type": "access"
}
ClaimDescription
subID unique de l'utilisateur
emailEmail de l'utilisateur
user_typeType : STUDENT, UNIVERSITY_ADMIN, ACADEMIC_SUPERVISOR, COMPANY, COMPANY_MENTOR, PLATFORM_ADMIN
expTimestamp d'expiration
type"access"

Refresh Token

{
"sub": "user_id_123",
"email": "user@example.com",
"user_type": "STUDENT",
"school_id": "school_456",
"exp": 1740086400,
"type": "refresh"
}

Différence : Le type est "refresh" au lieu de "access".

Durées de Vie

TokenDuréeConfiguration
Access Token30 minutesACCESS_TOKEN_EXPIRE_MINUTES
Refresh Token7 joursREFRESH_TOKEN_EXPIRE_DAYS

Flow Login

Code associé

  • Endpoint : POST /api/v1/auth/login
  • Service : AuthLoginService.login()
  • Fonction : create_tokens() (app/utils/auth.py)

Flow Requête Authentifiée

Code associé

  • Dépendance : get_current_user() (app/utils/dependencies.py)
  • Vérification : verify_token() (app/utils/auth.py)
  • Cache Redis : Clé auth:token:{user_id}, TTL 900s

Flow Refresh Token

Code associé

  • Endpoint : POST /api/v1/auth/refresh-token
  • Vérifications :
    • Token valide
    • User existe
    • User status ≠ INACTIVE/SUSPENDED

Flow Logout

Code associé

  • Endpoint : POST /api/v1/auth/logout
  • Actions :
    • Supprime le cache Redis auth:token:{user_id} (révocation partielle si Redis activé)
    • Appelle supabase.auth.sign_out() en background

Stockage des Tokens

Stockage actuel

Les tokens sont stockés côté frontend dans localStorage/sessionStorage.

Le backend retourne les tokens dans le corps de la réponse JSON (pas dans des cookies HttpOnly).

{
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"token_type": "bearer",
"expires_in": 1800,
"user_type": "STUDENT"
}

Le frontend doit les stocker lui-même (localStorage ou sessionStorage).

Configuration

Variables d'Environnement

VariableValeur par défautDescription
SECRET_KEY-Clé de signature JWT
ALGORITHMHS256Algorithme JWT
ACCESS_TOKEN_EXPIRE_MINUTES30Durée access token
REFRESH_TOKEN_EXPIRE_DAYS7Durée refresh token
REDIS_ENABLEDfalseActivation Redis
REDIS_HOSTredis://localhost:6379URL Redis

Lacunes de Sécurité

1. Tokens en localStorage

Problème : Les tokens sont exposés au JavaScript (XSS vulnerable).

Risque : Si une XSS existe, un attaquant peut voler les tokens.

Alternatives :

  • Cookies HttpOnly (recommandé)
  • HttpOnly + Secure + SameSite

2. Redis Désactivé par Défaut

Problème : REDIS_ENABLED=false par défaut.

Impact :

  • Pas de cache utilisateur
  • Pas de révocation de session efficace
  • Chaque requête interroge la DB

3. Pas de Blacklist de Tokens

Problème : Un token volé reste valide jusqu'à expiration.

Impact : Impossible de révoquer un token compromis rapidement.

4. Pas de Refresh Token Rotation

Problème : Le refresh token n'est pas renouvelé à chaque utilisation.

Impact : Un refresh token volé reste valide 7 jours.

Comment Déboguer

Vérifier un token

  1. Copier le token
  2. Aller sur https://jwt.io
  3. Vérifier la signature avec SECRET_KEY

Vérifier le cache Redis

redis-cli GET auth:token:{user_id}

Tester le login

curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "password": "password123"}'

Tester le logout

curl -X POST http://localhost:8000/api/v1/auth/logout \
-H "Authorization: Bearer {access_token}"

Fichiers Clés

FichierDescription
app/utils/auth.pycreate_tokens, verify_token
app/utils/dependencies.pyget_current_user
app/api/v1/routers/auth.pyEndpoints auth
app/core/config.pyConfiguration
app/core/redis_client.pyClient Redis