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
| Endpoint | Méthode | Auth | Description |
|---|---|---|---|
/auth/register | POST | Non | Créer un compte |
/auth/login | POST | Non | Obtenir un token JWT |
/api/me | GET | Bearer | Profil courant |
/api/projects | GET | Bearer | Projets de l'utilisateur |
/api/projects | POST | Bearer | Créer un projet |
/api/projects/{id} | DELETE | Bearer + Owner | Supprimer (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"}'