Para la autenticación en APIs desarrolladas con Symfony es muy habitual el uso del bundle LexikJWTAuthenticationBundle.
Su instalación es muy sencilla, únicamente es necesario agregarlo al composer.json del proyecto Symfony:
$ php composer.phar require "lexik/jwt-authentication-bundle"
generar las claves SSL (por defecto, se encontrarán en la carpeta config/jwt):
$ php bin/console lexik:jwt:generate-keypair
configurar el paquete:
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
y configurar la seguridad de la aplicación Symfony:
security:
enable_authenticator_manager: true
# ...
firewalls:
login:
pattern: ^/api/login
stateless: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/api
stateless: true
jwt: ~
access_control:
- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
No olvidar configurar la ruta indicada en el check_path:
api_login_check:
path: /api/login_check
Por defecto, cuando un usuario se autentique en nuestra API se devolverá un json como respuesta que cotendrá el token (JWT), pero es posible que queramos añadir algo más de información a esa respuesta. Para eso usaremos el evento AUTHENTICATION_SUCCESS del LexikJWTAuthenticationBundle.
Creamos la clase donde generaremos la respuesta:
<?php
namespace App\EventListener;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Symfony\Component\Security\Core\User\UserInterface;
class AuthenticationSuccessListener
{
public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event)
{
$data = $event->getData();
$user = $event->getUser();
if (!$user instanceof UserInterface) {
return;
}
$data['usuario'] = [
'nombre' => $user->getNombre(),
'email' => $user->getEmail(),
'roles' => $user->getRoles(),
];
$event->setData($data);
}
}
y lo configuramos en el fichero config/services.yaml:
services:
App\EventListener\AuthenticationSuccessListener:
tags:
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse }