Aller au contenu

Authentification Json Web Token - Symfony

Installation du bundle

Pour installer le bundle, nous allons utiliser composer.

Installation avec composer
composer require lexik/jwt-authentication-bundle

Génération d’une paire de clés

Pour générer une paire de clés, nous utiliserons la commande du bundle. Cette commande crée 2 clés (privée et publique) dans le répertoire config/jwt/, private.pem et public.pem.

Générer une paire de clés
php bin/console lexik:jwt:generate-keypair

Mise à jour du fichier security.yaml

Nous devons modifier le fichier security.yaml, nous pourrons l’ajuster en fonction de nos besoins.

config/packages/security.yaml
...
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
...
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login$
stateless: true
json_login:
check_path: /api/login
username_path: email
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
entry_point: jwt
jwt: ~
main:
lazy: true
provider: app_user_provider
...
access_control:
- { path: ^/$, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI
- { path: ^/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI docs
- { path: ^/api/login$, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
...

Configuration API Platform

Nous allons configurer API Platform grace au fichier api_platform.yaml.

config/packages/api_platform.yaml
...
api_platform:
swagger:
api_keys:
JWT:
name: Authorization
type: header

Ajout des informations nécessaires pour l’authentification

Nous ajoutons un point de terminaison à SwaggerUI pour récupérer un jeton JWT LexikJWTAuthenticationBundle pour un intégration avec API Platform, cela ajoutera un point terminaison OpenAPI pour récupérer le jeton dans l’interface utilisateur Swagger.

config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600

Modification des routes

Ajout de la route pour le login de l’utilisateur, dans config/routes.yaml.

config/routes.yaml
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute
api_login_check:
path: /api/login
path: /api/login_check

Tester l’authentification

Saisir bearer suivi de la clé publique Authorize JWT Authentication - API Platform

S’authentifier avec l’identifiant (email) et le mot de passe. Authentification API Platform

Token de réponse Response Authentification API Platform

Détail des informations dans le token Informations jwt.io

Modification du JWT à la création

Nous pouvons modifier le contenu de notre JWT en utilisant un Subscriber associé à un événement, voir la documentation, il va écouter l’événement exik_jwt_authentication.on_jwt_created.

Créer le EventSubscriber

Nous pouvons directement créer le Subscriber avec la commande ci-dessous, il nous faudra y renseigner l’événement.

Commande pour créer un Subscriber
php bin/console make:subscriber <Subscriber-name>

Éditer le Subscriber

Voici un exmple de Subscriber pour éditer les informations à renseigner dans le JWT, nous avons plusieurs méthodes disponibles.

  • getUser() ➡️ Nous permet de récupérer les informations de l’utilisateur.
  • getData() ➡️ Nous permet de récupérer les informations dans le token JWT.
  • getHeader() ➡️ Nous permet de récupérer les informations dans le header du token JWT.
src/EventSubscriber/JWTSubscriber.php
<?php
namespace App\EventSubscriber;
use App\Entity\User;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class JWTSubscriber implements EventSubscriberInterface
{
public function onLexikJwtAuthenticationOnJwtCreated(JWTCreatedEvent $event): void
{
/**
* Add information in the Token
*
* getUser();
* getData();
* getHeader();
*/
// Exemple de code pour modifier le token JWT
$data = $event->getData();
$user = $event->getuser();
if ($user instanceof User) {
$data['username'] = $user->getId();
}
$event->setData($data);
}
public static function getSubscribedEvents(): array
{
return [
'lexik_jwt_authentication.on_jwt_created' => 'onLexikJwtAuthenticationOnJwtCreated',
];
}
}