Ajout authentification JWT complète (app 100% protégée)

Backend:
- Nouveau module auth.py avec JWT et password handling
- Endpoint /api/auth/login (public)
- Endpoint /api/auth/me (protégé)
- TOUS les endpoints API protégés par require_auth
- Variables env: ADMIN_EMAIL, ADMIN_PASSWORD, JWT_SECRET_KEY
- Dependencies: python-jose, passlib

Frontend:
- Page de login (/login)
- AuthGuard component pour redirection automatique
- Axios interceptor: ajoute JWT token à chaque requête
- Gestion erreur 401: redirect automatique vers /login
- Bouton logout dans header
- Token stocké dans localStorage

Configuration:
- .env.example mis à jour avec variables auth
- Credentials admin configurables via env

Sécurité:
- Aucun endpoint public (sauf /api/auth/login et /health)
- JWT expiration configurable (24h par défaut)
- Password en clair dans env (à améliorer avec hash en prod)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-26 10:05:36 +01:00
parent 6ae861ff54
commit 774cb799a2
13 changed files with 522 additions and 11 deletions

34
frontend/lib/auth.ts Normal file
View File

@@ -0,0 +1,34 @@
/**
* Authentication utilities
*/
export function getToken(): string | null {
if (typeof window === "undefined") return null
return localStorage.getItem("access_token")
}
export function setToken(token: string): void {
localStorage.setItem("access_token", token)
}
export function removeToken(): void {
localStorage.removeItem("access_token")
localStorage.removeItem("user")
}
export function getUser(): any | null {
if (typeof window === "undefined") return null
const user = localStorage.getItem("user")
return user ? JSON.parse(user) : null
}
export function isAuthenticated(): boolean {
return getToken() !== null
}
export function logout(): void {
removeToken()
if (typeof window !== "undefined") {
window.location.href = "/login"
}
}