Skip to content

Sécurité & Authentification

🔑 JWT (JSON Web Token)

L'authentification est gérée via LexikJWTAuthenticationBundle. Les routes sont segmentées en deux zones via le firewall Symfony : une zone publique (catalogue, recherche) et une zone sécurisée (commandes, profil, administration).

Flux d'authentification

sequenceDiagram
    participant C as Client
    participant API as API Symfony
    participant DB as PostgreSQL

    C->>API: POST /api/v1/login_check<br/>{ email, password }
    API->>DB: Vérifie les credentials (bcrypt)
    DB-->>API: User entity
    API-->>C: 200 OK { token: "eyJ..." }

    Note over C,API: Requêtes authentifiées suivantes

    C->>API: GET /api/v1/orders<br/>Authorization: Bearer eyJ...
    API->>API: Vérifie la signature JWT<br/>et l'expiration du token
    API-->>C: 200 OK + données JSON

Configuration des zones Firewall

Zone Pattern Accès
api_public /api/v1/products, /api/v1/categories Anonyme
api_secured /api/v1/orders, /api/v1/admin/** Token JWT requis

🛡️ Autorisations Granulaires (Voters)

La hiérarchie de rôles classique (ROLE_USER, ROLE_ADMIN) est insuffisante pour modéliser des règles métier complexes. Les Voters Symfony permettent d'exprimer ces règles directement en code, de manière explicite et testable.

Segmentation des acteurs

Type d'acteur Rôle Symfony Périmètre d'accès
CUSTOMER ROLE_CUSTOMER Tunnel de commande, ses propres commandes, ses avis
INTERNAL ROLE_INTERNAL Consultation des stocks, gestion des expéditions
ADMIN ROLE_ADMIN Accès total : catalogue, utilisateurs, transporteurs

Exemple : OrderVoter

Un utilisateur authentifié ne peut accéder qu'à ses propres commandes. Le RoleHierarchy seul ne peut pas exprimer cette règle — c'est le rôle du Voter :

protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
{
    /** @var User $user */
    $user = $token->getUser();

    // Seul un profil CUSTOMER peut créer une commande
    if ($attribute === self::CREATE) {
        return in_array('ROLE_CUSTOMER', $user->getRoles());
    }

    // Un utilisateur ne peut consulter QUE ses propres commandes
    if ($attribute === self::VIEW) {
        return $subject->getCustomer()->getId() === $user->getId();
    }

    return false;
}

Avantage : La règle métier est co-localisée avec la ressource concernée (OrderVoterOrder). Elle est lisible, explicite et testable unitairement sans contexte HTTP.