@un-dev-suisse/nestjs-cookie
v1.0.1
Published
Librairie complète pour la gestion des cookies dans NestJS avec validation, sécurité et facilité d'utilisation
Maintainers
Readme
@un-dev-suisse/nestjs-cookie
Une librairie complète pour la gestion des cookies dans les applications NestJS avec validation, sécurité et facilité d'utilisation.
Installation
npm install @un-dev-suisse/nestjs-cookieou
pnpm install @un-dev-suisse/nestjs-cookieUtilisation
1. Importer le module
import { Module } from '@nestjs/common';
import { CookieModule } from '@un-dev-suisse/nestjs-cookie';
@Module({
imports: [CookieModule],
})
export class AppModule {}2. Utiliser le service CookieService
import { Injectable } from '@nestjs/common';
import { CookieService } from '@un-dev-suisse/nestjs-cookie';
@Injectable()
export class MyService {
constructor(private readonly cookieService: CookieService) {}
// Extraire un cookie spécifique
getSessionId(cookieHeader: string): string {
return this.cookieService.getCookie('sessionId', cookieHeader);
}
// Parser tous les cookies
getAllCookies(cookieHeader: string) {
return this.cookieService.getCookies(cookieHeader);
}
// Vérifier l'existence d'un cookie
hasSessionCookie(cookieHeader: string): boolean {
return this.cookieService.hasCookie('sessionId', cookieHeader);
}
// Supprimer un cookie
deleteSessionCookie(): string {
return this.cookieService.deleteCookie('sessionId', 'example.com', '/');
}
}3. Utiliser la classe Cookie
import { Cookie } from '@un-dev-suisse/nestjs-cookie';
// Créer un cookie simple
const sessionCookie = new Cookie('sessionId', 'abc123');
// Créer un cookie avec options personnalisées
const secureCookie = new Cookie('sessionId', 'abc123', {
Domain: 'example.com',
Path: '/admin',
Secure: true,
HttpOnly: true,
SameSite: 'Strict',
MaxAge: 3600, // 1 heure
});
// Utiliser le chaînage de méthodes
const customCookie = new Cookie('sessionId', 'abc123')
.setDomain('example.com')
.setPath('/admin')
.setSameSite('Strict')
.setSecure(true)
.setHttpOnly(true)
.setMaxAge(3600);
// Générer la chaîne pour l'en-tête Set-Cookie
const cookieString = customCookie.toString();
// Résultat: sessionId=abc123; Domain=example.com; Path=/admin; SameSite=Strict; Secure; HttpOnly; Max-Age=3600API
CookieService
getCookie(name: string, cookieString: string): string
Extrait la valeur d'un cookie spécifique depuis une chaîne de cookies.
Paramètres :
name: Nom du cookie à extrairecookieString: Chaîne de cookies complète
Retourne : Valeur du cookie ou chaîne vide si non trouvé
getCookies(cookieString: string): CookieData
Parse une chaîne de cookies et retourne un objet avec tous les cookies.
Paramètres :
cookieString: Chaîne de cookies à parser
Retourne : Objet contenant tous les cookies
hasCookie(name: string, cookieString: string): boolean
Vérifie si un cookie existe dans une chaîne de cookies.
deleteCookie(name: string, domain?: string, path?: string): string
Supprime un cookie en générant une chaîne de suppression.
isValidCookieName(name: string): boolean
Valide le nom d'un cookie selon les standards RFC 6265.
isValidCookieValue(value: string): boolean
Valide la valeur d'un cookie.
Cookie (Classe)
Constructeur
new Cookie(name: string, value: string, customOptions?: Partial<CookieOptions>)Méthodes de configuration
setDomain(domain: string): thissetPath(path: string): thissetSameSite(sameSite: SameSiteValue): thissetSecure(secure: boolean): thissetHttpOnly(httpOnly: boolean): thissetMaxAge(seconds: number): thissetExpires(date: Date): this
Méthodes utilitaires
disable(options: (keyof CookieOptions)[]): thisenable(options: (keyof CookieOptions)[]): thissetOption<K>(option: K, value: CookieOptions[K]): this
Getters
getName(): stringgetValue(): stringgetOptions(): Readonly<CookieOptions>
toString(): string
Convertit le cookie en chaîne de caractères pour l'en-tête Set-Cookie.
Types et Interfaces
CookieData
interface CookieData {
[key: string]: string;
}CookieOptions
interface CookieOptions {
Domain?: string;
Path?: string;
Secure?: boolean;
HttpOnly?: boolean;
SameSite?: 'Strict' | 'Lax' | 'None';
MaxAge?: number;
Expires?: Date;
}SameSiteValue
type SameSiteValue = 'Strict' | 'Lax' | 'None';Configuration par défaut
const DEFAULT_COOKIE_CONFIG: CookieOptions = {
Domain: process.env.COOKIE_DOMAIN,
Path: '/',
Secure: process.env.APP_ENV !== 'dev',
HttpOnly: true,
SameSite: 'Lax',
MaxAge: 3600 * 24 * 30, // 30 jours
};Gestion d'erreurs
Le service et la classe incluent une validation complète :
- Validation des noms de cookies selon RFC 6265
- Validation des valeurs de cookies
- Validation des options de cookies
- Messages d'erreur explicites
Exemples d'erreurs
// Nom de cookie invalide
new Cookie('session id', 'abc123'); // Error: Le nom du cookie contient des caractères invalides
// Valeur trop longue
new Cookie('sessionId', 'a'.repeat(4097)); // Error: La valeur du cookie est trop longue
// Option SameSite invalide
cookie.setSameSite('Invalid'); // Error: SameSite doit être Strict, Lax ou NoneSécurité
Bonnes pratiques implémentées
- Validation RFC 6265 : Respect des standards pour les noms et valeurs
- Encodage automatique : Les valeurs sont automatiquement encodées/décodées
- Options sécurisées par défaut : HttpOnly, Secure (en production), SameSite
- Gestion d'environnement : Secure désactivé en développement
- Validation stricte : Toutes les entrées sont validées
Configuration sécurisée recommandée
const secureCookie = new Cookie('sessionId', 'abc123')
.setSecure(true) // HTTPS uniquement
.setHttpOnly(true) // Pas d'accès JavaScript
.setSameSite('Strict') // Protection CSRF
.setMaxAge(3600); // Expiration courteExemples d'utilisation
Dans un contrôleur NestJS
import { Controller, Get, Res, Req } from '@nestjs/common';
import { Response, Request } from 'express';
import { CookieService, Cookie } from '@un-dev-suisse/nestjs-cookie';
@Controller('auth')
export class AuthController {
constructor(private readonly cookieService: CookieService) {}
@Get('login')
async login(@Res() res: Response) {
// Créer un cookie de session
const sessionCookie = new Cookie('sessionId', 'abc123')
.setHttpOnly(true)
.setSecure(true)
.setSameSite('Strict')
.setMaxAge(3600);
res.setHeader('Set-Cookie', sessionCookie.toString());
res.json({ message: 'Logged in' });
}
@Get('profile')
async getProfile(@Req() req: Request) {
const cookieHeader = req.headers.cookie || '';
const sessionId = this.cookieService.getCookie('sessionId', cookieHeader);
if (!sessionId) {
return { error: 'Not authenticated' };
}
return { sessionId, message: 'Profile data' };
}
@Get('logout')
async logout(@Res() res: Response) {
// Supprimer le cookie
const deleteCookie = this.cookieService.deleteCookie('sessionId', 'example.com');
res.setHeader('Set-Cookie', deleteCookie);
res.json({ message: 'Logged out' });
}
}Gestion des cookies multiples
// Parser tous les cookies
const allCookies = this.cookieService.getCookies(cookieHeader);
console.log(allCookies); // { sessionId: 'abc123', theme: 'dark', lang: 'fr' }
// Vérifier plusieurs cookies
const hasSession = this.cookieService.hasCookie('sessionId', cookieHeader);
const hasTheme = this.cookieService.hasCookie('theme', cookieHeader);Tests
La librairie inclut une suite de tests complète couvrant :
- ✅ Toutes les méthodes du service
- ✅ Toutes les méthodes de la classe
- ✅ Validation et gestion d'erreurs
- ✅ Cas limites et edge cases
- ✅ Gestion d'environnement
- ✅ Sécurité et encodage
Licence
MIT
