Objectif

Construire une API sécurisée avec authentification JWT complète : inscription, connexion, routes protégées par token, et gestion des projets par utilisateur.

Stack : FastAPI + SQLAlchemy (SQLite) + python-jose + passlib[bcrypt] + python-dotenv

Endpoints

EndpointMéthodeAuthDescription
/auth/registerPOSTNonCréer un compte
/auth/loginPOSTNonObtenir un token JWT
/api/meGETBearerProfil courant
/api/projectsGETBearerProjets de l'utilisateur
/api/projectsPOSTBearerCréer un projet
/api/projects/{id}DELETEBearer + OwnerSupprimer (IDOR check)

Structure

05-api-rest/mini-projet/solution/
├── main.py          # App FastAPI + routes
├── auth.py          # JWT, bcrypt, get_current_user
├── models.py        # User, Project (SQLAlchemy)
├── schemas.py       # Pydantic schemas
├── .env.example     # Variables d'environnement
└── requirements.txt

Flux d'authentification

1. POST /auth/register  {email, password}
        → 201 {id, email}

2. POST /auth/login  form-data: {username=email, password}
        → 200 {access_token, token_type: "bearer"}

3. GET /api/projects
   Header: Authorization: Bearer <token>
        → FastAPI extrait le token via OAuth2PasswordBearer
        → get_current_user() décode et valide
        → La route reçoit current_user
        → 200 [{id, name, ...}]

Tests curl

# 1. Inscription
curl -X POST http://localhost:8000/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@test.com","password":"alice123","username":"alice"}'

# 2. Login (form-data !)
curl -X POST http://localhost:8000/auth/login \
  -d "username=alice@test.com&password=alice123"

# 3. Sauvegarder le token
TOKEN="eyJ..."

# 4. Profil protégé
curl http://localhost:8000/api/me \
  -H "Authorization: Bearer $TOKEN"

# 5. Créer un projet (protégé)
curl -X POST http://localhost:8000/api/projects \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Mon Projet","description":"Description"}'
← Retour au cours 🧠 QCM Module 05 Module 06 — Validation →