Gestion des jetons d'authentification avec API Platform

Vous venez de gérer l'authentification avec les JWT et le bundle Lexic Authentication JWT dans une API créée avec Symfony. Mais qu'en est-il avec API Platform ?

Heureusement, API Platform supporte, et même conseille, l'utilisation de ce bundle pour gérer l'authentification.

Utilisons un projet déjà créé afin de le sécuriser avec les JWT. La démarche sera exactement la même que précédemment, seuls quelques ajouts seront faits afin de gérer, notamment, la documentation de l'API.

Méthode

Comme précédemment, il faut créer une entité User à l'aide de la commande bin/console make:user (puis bien sûr, générer une migration et l'exécuter en base de données).

Le bundle Lexic Authentication JWT doit ensuite être installé avec composer, et les clés publiques et privées doivent être générées dans le dossier « config/jwt ».

Remarque

La clé privée et la clé publique ne doivent pas être versionnées, il faut donc les ajouter dans le .gitignore afin qu'elles ne soient pas prises en compte par git.

Méthode

Vous allez maintenant renseigner le chemin des clés générées ainsi que le mot de passe utilisé dans votre fichier .env.local, comme dans la section précédente.

Il ne vous reste plus qu'à configurer le composant Security de Symfony et à créer la route de login, en utilisant les mêmes informations que précédemment.

Et une fois de plus, la sécurisation de votre API est en place !

Mais il y a un léger accroc. En effet la documentation de l'API, générée API Platform via l'outil Swagger, n'est plus accessible : la page demande à ce que le client soit authentifié avant de pouvoir y accéder. Ce qui est tout à fait normal, car l'URL de la documentation est « /api ».

Afin de rendre cette URL disponible, il suffit de ne sécuriser que les URLs commençant par « /api/ » et non « /api » :

ExempleCode

1
#config/packages/security.yaml
2
3
security:
4
    encoders:
5
        App\Entity\User:
6
            algorithm: auto
7
8
    providers:
9
        # used to reload user from session & other features (e.g. switch_user)
10
        app_user_provider:
11
            entity:
12
                class: App\Entity\User
13
                property: username
14
15
    firewalls:
16
        dev:
17
            pattern: ^/(_(profiler|wdt)|css|images|js)/
18
            security: false
19
        login:
20
            pattern:  ^/api/login
21
            stateless: true
22
            anonymous: true
23
            json_login:
24
                check_path: /api/login
25
                username_path: username
26
                password_path: password
27
                success_handler:          lexik_jwt_authentication.handler.authentication_success
28
                failure_handler:          lexik_jwt_authentication.handler.authentication_failure
29
        api:
30
            pattern:   ^/api/
31
            stateless: true
32
            guard:
33
                authenticators:
34
                    - lexik_jwt_authentication.jwt_token_authenticator
35
36
    access_control:
37
       - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
38
        - { path: ^/api/,       roles: IS_AUTHENTICATED_FULLY }
39
40

Remarque

Les rôles de l'utilisateur peuvent être utilisés pour rendre accessible ou non chaque opération sur des ressources. En effet, dans l'annotation @ApiResource() de chaque ressource, vous pouvez, pour chaque opération, ajouter le rôle que l'utilisateur doit pour accéder à la ressource. Plus d'infos ici : ApiResource access_control.

Méthode

La documentation Swagger de votre API est à nouveau disponible. Mais vous ne pouvez plus y tester nos endpoints car le token est obligatoire ! C'est là aussi normal : si vous voulez que la documentation soit visible par tous, les données de votre API ne doivent par contre pas être accessibles et modifiables aux utilisateurs non authentifiés, ce qui implique de sécuriser également les endpoints de la documentation.

Afin de pouvoir renseigner le token lors des appels faits depuis la documentation, il faut modifier le fichier de configuration d'API Platform :

ExempleCode

1
# config/packages/api_platform.yaml
2
api_platform:
3
    title: 'Symfony REST API'
4
    description: 'À Symfony API to manage a simple blog app.'
5
    version: '1.0.0'
6
    mapping:
7
        paths: ['%kernel.project_dir%/src/Entity']
8
    patch_formats:
9
        json: ['application/merge-patch+json']
10
    swagger:
11
        versions: [3]
12
        api_keys:
13
          apiKey:
14
            name: Authorization
15
            type: header
16

Pour renseigner le token depuis la documentation, il faut désormais utiliser le bouton « Authorize » présent en haut à droite de la documentation, puis y inscrire « Bearer » suivi du token.

Votre API et votre documentation d'API créées avec API Platform sont maintenant sécurisées grâce aux JWT !

Fondamental

  • L'authentification avec les JWT et API Platform utilise le même bundle et la même configuration que pour une API créée seulement avec Symfony.

  • La documentation de Swagger peut être rendue publique, tout en sécurisant les points d'API que l'on peut utiliser. La configuration d'une clé d'API dans API Platform permet d'ajouter la possibilité de remplir le token depuis la documentation.

  • Les clés publiques et privées, que ce soit avec API Platform ou sans, ne doivent pas être versionnées.