Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Auth & Identity Service

Microservice d'authentification et gestion d'identité construit avec FastAPI, PostgreSQL et Redis.
Mecanisme JWT asymetrique (RS256), refresh token rotation, rate limiting distribue, et blacklist temps reel.


Architecture

Client  -->  API Gateway  -->  Auth Service (:8080)  -->  PostgreSQL (auth_identity_db)
                                  |
                                  v
                               Redis (rate limit + blacklist)
  • Chiffrement RS256 : seule l'Auth Service detient la cle privee. Les autres services recoivent la cle publique via /jwks.json.
  • Access Token (15 min) : transmis dans le body JSON, destine a la memoire volatile du client.
  • Refresh Token (7 jours) : cookie HttpOnly + Secure + SameSite=Strict. Le JavaScript n'y a pas acces.

Principe de fonctionnement

  1. L'API Gateway valide l'Access Token avec la cle publique.
  2. La Gateway injecte X-User-Id et X-User-Role dans les requetes aval.
  3. Chaque microservice peut re-verifier via get_current_user() (FastAPI dependency).

Demarrage rapide

Prérequis

  • Python 3.12+
  • PostgreSQL (ou base de donnees accessible)
  • Redis (optionnel : fallback automatique vers MockRedis en memoire)

Installation

pip install -r requirements.txt

# Generer les cles RSA (si absentes)
python generate_keys.py

Configuration

Variables d'environnement (ou fichier .env) :

Variable Defaut Description
DATABASE_URL postgresql+asyncpg://postgres:postgres@localhost:5432/auth_identity_db Connexion PostgreSQL
REDIS_URL redis://localhost:6379/0 Connexion Redis
RSA_PRIVATE_KEY_PATH ./keys/private_key.pem Chemin de la cle privee
RSA_PUBLIC_KEY_PATH ./keys/public_key.pem Chemin de la cle publique
INTERNAL_SERVICE_SECRET super-secret-internal-token Jeton pour les routes internes
PORT 8080 Port d'ecoute
COOKIE_SECURE False Secure flag sur le cookie (mettre True en prod HTTPS)

Lancement

uvicorn main:app --port 8080 --reload

Structure du projet

auth_service_fastAPI/
  main.py                  # Point d'entree FastAPI
  generate_keys.py         # Utilitaire de generation RSA
  keys/                    # Cles PEM (generees)
  app/
    config.py              # Pydantic Settings
    database.py            # Engine async SQLAlchemy + session
    models.py              # ORM : User, Profile, RefreshToken
    schemas.py             # Pydantic v2 validation
    security.py            # JWT, hash, JWKS
    redis.py               # Client Redis + MockRedis fallback
    dependencies.py        # Dependencies FastAPI (auth, roles, interne)
    routers/
      auth.py              # /api/v1/auth/*
      profiles.py          # /api/v1/profiles/*
      admin.py             # /api/v1/admin/*
      internal.py          # /internal/v1/*

API Reference

Authentification

Methode Chemin Acces Description
POST /api/v1/auth/register Public Inscription (users + profiles, transaction atomique)
POST /api/v1/auth/login Public Connexion (rate limite: 5 req/min/IP)
POST /api/v1/auth/refresh Cookie Rotation du refresh token, nouveau access token
POST /api/v1/auth/logout Connecte Revocation du refresh token + suppression cookie
GET /api/v1/auth/.well-known/jwks.json Public Cle publique au format JWKS

Profils

Methode Chemin Acces Description
GET /api/v1/profiles/me Connecte Profil complet de l'utilisateur courant
PUT /api/v1/profiles/me Connecte Mise a jour du profil courant
GET /api/v1/profiles/{user_id} Public Profil public (donnees sensibles masquees)

Administration

Methode Chemin Acces Description
PATCH /api/v1/admin/users/{user_id}/ban Admin Bannissement (is_active=False + blacklist Redis)

Inter-services (protege par X-Internal-Service-Token)

Methode Chemin Description
GET /internal/v1/users/{id}/access Controle d'acces pour l'API Gateway
GET /internal/v1/users/{id}/payout-identity Donnees d'identite pour le service Paiement

Schema de donnees

users (1) ----- (1) profiles
  |
  | (N)
  v
refresh_tokens

users

Champ Type Contrainte
id UUID PK, uuid4
email VARCHAR(255) Unique, indexe, normalise (lower + strip)
password_hash VARCHAR(255) Bcrypt
role VARCHAR(50) USER, STUDENT, ADMIN, MODERATOR
is_active BOOLEAN True defaut, False si banni
is_verified BOOLEAN False defaut
created_at / updated_at TIMESTAMPTZ Auto

profiles

Champ Type Contrainte
id UUID PK
user_id UUID FK -> users.id, CASCADE
first_name / last_name VARCHAR(100) Nullable
avatar_url VARCHAR(500) Nullable
bio TEXT Nullable
phone VARCHAR(30) Nullable, masque en public

refresh_tokens

Champ Type Contrainte
id UUID PK
user_id UUID FK -> users.id
token_hash VARCHAR(255) SHA-256 du token
expires_at TIMESTAMPTZ 7 jours
is_revoked BOOLEAN False defaut

Securite

Refresh Token Rotation

A chaque appel /refresh :

  • L'ancien refresh token est marque is_revoked = True.
  • Un nouveau token est emis (cookie + hash en base).
  • Si un token deja revoke est presente : tous les refresh tokens de l'utilisateur sont revoques (detection de vol de session).

Blacklist temps reel (Redis)

Lors d'un bannissement :

  1. is_active = False en base.
  2. Tous les refresh tokens revoques.
  3. Cle blacklist:user:{id} inseree dans Redis (TTL = duree de vie de l'access token).
  4. Les dependances FastAPI verifient cette blacklist avant chaque action.

Rate Limiting

  • /login : 5 tentatives par minute par IP (cle rate:login:{ip} dans Redis).
  • Au-dela : HTTP 429 avec message explicite.

Protection inter-services

Les routes /internal/* verifient l'en-tete X-Internal-Service-Token par comparaison stricte avec la variable INTERNAL_SERVICE_SECRET.


Format des reponses d'erreur

Toutes les erreurs suivent le format RFC 7807 :

{
  "detail": "Email ou mot de passe incorrect",
  "code": "AUTHENTICATION_FAILED"
}

Codes d'erreur courants :

  • INVALID_TOKEN : Token JWT invalide ou expire
  • AUTHENTICATION_REQUIRED : Aucun token fourni
  • ACCOUNT_SUSPENDED : Utilisateur blackliste
  • ACCOUNT_DISABLED : Compte desactive
  • FORBIDDEN : Role insuffisant
  • VALIDATION_ERROR : Donnees d'entree invalides
  • RATE_LIMIT_EXCEEDED : Trop de tentatives
  • SESSION_COMPROMISED : Vol de session detecte

Instructions pour les equipes

Frontend

  • Ne pas extraire le refresh token du cookie. Le navigateur le transmet automatiquement.
  • Utiliser credentials: 'include' (fetch) ou withCredentials: true (axios).
  • Stocker l'access token en memoire (variable JS), pas dans localStorage.

DevOps

  • Generer les cles RSA en production et les monter via /etc/secrets/.
  • Configurer COOKIE_SECURE=True en production (HTTPS obligatoire).
  • S'assurer que le secret INTERNAL_SERVICE_SECRET est partage de maniere securisee entre services.

Developpement

Creer la base de donnees

psql -U postgres -c "CREATE DATABASE auth_identity_db;"

Tests (a venird)

pytest scratch/run_tests.py -v

About

micro service d'authentification sécurisé avec FASTAPI

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages