Для добавления возможности аутентификации по JWT токену в Symfony, необходимо выполнить несколько шагов.
Шаг 1: Установка необходимых зависимостей
Для начала, установите необходимые зависимости, такие как lexik/jwt-authentication-bundle
и firebase/php-jwt
. Выполните следующую команду в корневой директории вашего Symfony проекта:
composer require lexik/jwt-authentication-bundle firebase/php-jwt
Шаг 2: Конфигурация бандла
После установки зависимостей, откройте файл config/bundles.php
и добавьте следующую строку:
LexikBundleJWTAuthenticationBundleLexikJWTAuthenticationBundle::class => ['all' => true],
Затем, откройте файл config/packages/lexik_jwt_authentication.yaml
и настройте его следующим образом:
lexik_jwt_authentication: secret_key: "%env(resolve:APP_SECRET)%" public_key: "%env(resolve:JWT_PUBLIC_KEY_PATH)%" private_key_passphrase: "%env(JWT_PASSPHRASE)%" authentication_header: 'Bearer' token_ttl: 3600
Шаг 3: Создание пользовательской аутентификации
Symfony предоставляет инструмент для создания пользовательской аутентификации - UserProvider. Создайте класс src/Security/UserProvider/JwtUserProvider.php
и определите его следующим образом:
<?php namespace AppSecurityUserProvider; use LexikBundleJWTAuthenticationBundleSecurityUserJWTUserInterface; use LexikBundleJWTAuthenticationBundleSecurityUserJWTUserProviderInterface; use SymfonyComponentSecurityCoreExceptionUnsupportedUserException; use SymfonyComponentSecurityCoreExceptionUserNotFoundException; use SymfonyComponentSecurityCoreUserUserInterface; class JwtUserProvider implements JWTUserProviderInterface { public function loadUserByIdentifier(string $identifier): UserInterface { // реализация загрузки пользователя по идентификатору, например из базы данных } public function loadUserByUsername(string $username): UserInterface { // реализация загрузки пользователя по имени пользователя, например из базы данных } public function loadUserByPayload(array $payload): UserInterface { // реализация загрузки пользователя по данным токена, например из базы данных } public function refreshUser(UserInterface $user): UserInterface { // реализация обновления пользователя, например, проверка данных пользователя } public function supportsClass(string $class): bool { $supportedClass = JWTUserInterface::class; return $class === $supportedClass || is_subclass_of($class, $supportedClass); } }
Затем, необходимо зарегистрировать этот сервис в config/services.yaml
, добавив следующую строку:
services: AppSecurityUserProviderJwtUserProvider: arguments: - '@doctrine' tags: - { name: lexik_jwt_authentication.user_provider }
Шаг 4: Настройка аутентификации
Откройте файл config/packages/security.yaml
и настройте аутентификацию следующим образом:
security: encoders: AppEntityUser: bcrypt providers: jwt_user_provider: id: AppSecurityUserProviderJwtUserProvider firewalls: main: pattern: ^/ anonymous: true stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator access_control: - { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Шаг 5: Генерация JWT токена
Теперь, вы можете генерировать JWT токен, используя сервис lexik_jwt_authentication.encoder
и метод encode
:
$encoder = $this->get('lexik_jwt_authentication.encoder'); $token = $encoder->encode(['username' => 'user']);
Шаг 6: Проверка аутентификации
Для проверки аутентификации по JWT токену, вы можете использовать аннотацию @IsGranted
в ваших контроллерах, например:
use SymfonyBundleFrameworkBundleControllerAbstractController; use SymfonyComponentRoutingAnnotationRoute; use SensioBundleFrameworkExtraBundleConfigurationIsGranted; class ExampleController extends AbstractController { /** * @Route("/example", name="example_route") * @IsGranted("ROLE_USER") */ public function exampleAction() { // реализация действий для аутентифицированного пользователя } }
Это позволит вам ограничить доступ к определенным роутам только для аутентифицированных пользователей с правильной ролью.
Вот и все! Теперь вы имеете возможность аутентифицировать пользователей по JWT токену в Symfony с использованием бандла lexik/jwt-authentication-bundle
.