Module Auth
Module d'authentification et d'autorisation pour la MyTelevision API.
Vue d'ensemble
Le module Auth gere :
- Authentification JWT (access token + refresh token)
- Authentification sociale via Firebase (Google, Apple, Facebook)
- Rotation des tokens (refresh token rotation)
- Gestion des sessions (Redis)
- Rate limiting par endpoint
Architecture
Flux d'Authentification
Login Standard
Authentification Sociale
Structure des Fichiers
src/
├── application/
│ ├── dtos/
│ │ └── auth/
│ │ ├── login.dto.ts
│ │ ├── register.dto.ts
│ │ ├── refresh-token.dto.ts
│ │ ├── social-auth.dto.ts
│ │ └── auth-response.dto.ts
│ └── services/
│ └── auth/
│ ├── auth.service.ts
│ └── auth.service.spec.ts
├── infrastructure/
│ ├── guards/
│ │ ├── jwt-auth.guard.ts
│ │ ├── jwt-refresh.guard.ts
│ │ └── roles.guard.ts
│ └── strategies/
│ ├── jwt.strategy.ts
│ └── jwt-refresh.strategy.ts
└── presentation/
├── controllers/
│ └── api/v2/
│ └── auth.controller.ts
└── modules/
└── auth.module.ts
Composants Principaux
AuthService
Service principal gerant la logique d'authentification :
@Injectable()
export class AuthService {
async login(dto: LoginDto): Promise<AuthResponseDto>;
async register(dto: RegisterDto): Promise<AuthResponseDto>;
async refreshTokens(refreshToken: string): Promise<AuthResponseDto>;
async logout(userId: string, sessionId: string): Promise<void>;
async socialAuth(provider: string, idToken: string): Promise<AuthResponseDto>;
}
FirebaseService
Gestion de la verification des tokens Firebase :
@Injectable()
export class FirebaseService {
async verifyIdToken(idToken: string): Promise<DecodedIdToken>;
async getUserByEmail(email: string): Promise<UserRecord>;
getProviderFromToken(decodedToken: DecodedIdToken): SocialAuthProvider;
}
JwtAuthGuard
Protection des routes necessitant une authentification :
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
canActivate(context: ExecutionContext): boolean | Promise<boolean>;
handleRequest(err: any, user: any, info: any): any;
}
DTOs
LoginDto
export class LoginDto {
@IsEmail()
email: string;
@IsString()
@MinLength(8)
password: string;
@IsOptional()
@IsString()
deviceId?: string;
}
SocialAuthDto
export class SocialAuthDto {
@IsString()
@IsNotEmpty()
idToken: string;
@IsOptional()
@IsString()
deviceId?: string;
}
AuthResponseDto
export class AuthResponseDto {
accessToken: string;
refreshToken: string;
expiresIn: number;
user: UserResponseDto;
}
Guards
Utilisation des Guards
// Authentification requise
@UseGuards(JwtAuthGuard)
@Get('profile')
getProfile(@CurrentUser() user: User) {
return user;
}
// Roles specifiques requis
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
@Get('admin/users')
getUsers() {
// Admin uniquement
}
Configuration des Tokens
| Parametre | Valeur | Description |
|---|---|---|
| Access Token TTL | 15 minutes | Courte duree pour la securite |
| Refresh Token TTL | 7 jours | Duree plus longue pour le confort |
| Algorithme | HS256 | HMAC SHA-256 |
| Issuer | mytv-api | Claim issuer du token |
Mesures de Securite
Exigences de Mot de Passe
- Minimum 8 caracteres
- Au moins une lettre majuscule
- Au moins une lettre minuscule
- Au moins un chiffre
- Au moins un caractere special
Rate Limiting
| Endpoint | Limite | Fenetre |
|---|---|---|
/auth/login | 5 requetes | 1 minute |
/auth/register | 3 requetes | 1 minute |
/auth/refresh | 10 requetes | 1 minute |
Rotation des Tokens
Les refresh tokens sont renouveles a chaque utilisation :
- Le client envoie le refresh token
- Le serveur valide et invalide l'ancien token
- Le serveur emet de nouveaux access + refresh tokens
- L'ancien refresh token ne peut plus etre reutilise
Strategie de Liaison des Comptes Sociaux
Ordre de priorite pour la liaison de comptes :
- Recherche par
provider + providerUserId(compte social existant) - Recherche par
firebaseUid(utilisateurs Firebase legacy) - Recherche par
email(liaison avec un compte email existant) - Creation d'un nouvel utilisateur (premiere inscription)
Variables d'Environnement
# Configuration JWT
JWT_SECRET=your-secret-min-32-chars
JWT_REFRESH_SECRET=another-secret-min-32-chars
JWT_EXPIRATION=15m
JWT_REFRESH_EXPIRATION=7d
# Firebase (pour l'auth sociale)
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
FIREBASE_CLIENT_EMAIL=[email protected]
Codes d'Erreur
| Code | Message | Description |
|---|---|---|
| AUTH_001 | Invalid credentials | Email ou mot de passe incorrect |
| AUTH_002 | Token expired | Le token d'acces a expire |
| AUTH_003 | Invalid token | Token malformed ou altere |
| AUTH_004 | Account locked | Trop de tentatives echouees |
| AUTH_005 | Email not verified | Verification email requise |
| AUTH_006 | Social auth failed | Token Firebase invalide |
Tests
describe('AuthService', () => {
it('should login with valid credentials', async () => {
const result = await authService.login({
email: '[email protected]',
password: 'Password123!',
});
expect(result.accessToken).toBeDefined();
expect(result.refreshToken).toBeDefined();
});
it('should reject invalid password', async () => {
await expect(
authService.login({
email: '[email protected]',
password: 'wrong',
}),
).rejects.toThrow(UnauthorizedException);
});
});