Как создать rest API аутентификацию на Symfony?

Для создания REST API аутентификации на Symfony вам потребуется использовать пакет "LexikJWTAuthenticationBundle", который обеспечит вам возможность аутентификации через JSON Web Tokens (JWT).

Вот пошаговая инструкция по настройке аутентификации:

Шаг 1: Установка необходимых зависимостей
Установите пакет "LexikJWTAuthenticationBundle" с помощью Composer:

composer require lexik/jwt-authentication-bundle

Шаг 2: Конфигурация пакета
Откройте файл 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: '%env(JWT_TOKEN_TTL)%'
    clock_skew: '%env(JWT_CLOCK_SKEW)%'
    user_identity_field: email

Вы можете использовать любую другую конфигурацию, а эти значения можно настроить через переменные окружения.

Шаг 3: Создание аутентификационного контроллера
Откройте файл src/Controller/SecurityController.php и создайте новый контроллер с двумя методами: login() и refreshToken().

Метод login() будет принимать запрос с данными пользователя (например, email и пароль), осуществлять аутентификацию пользователя и выдавать токен JWT в случае успешной аутентификации.

Метод refreshToken() будет принимать запрос с истекшим токеном и выдавать новый токен JWT.

Пример кода контроллера может выглядеть следующим образом:

<?php

namespace AppController;

use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentRoutingAnnotationRoute;
use LexikBundleJWTAuthenticationBundleEncoderJWTEncoderInterface;
use SymfonyComponentSecurityCoreEncoderUserPasswordEncoderInterface;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentSecurityCoreUserUserInterface;

class SecurityController extends AbstractController
{
    /**
     * @Route("/api/login", name="api_login", methods={"POST"})
     */
    public function login(Request $request, UserPasswordEncoderInterface $encoder, JWTEncoderInterface $jwtEncoder)
    {
        $data = json_decode($request->getContent(), true);

        $user = $this->getDoctrine()->getRepository(User::class)->findOneBy(['email' => $data['email']]);

        if (!$user) {
            throw $this->createNotFoundException('User not found.');
        }

        if (!$encoder->isPasswordValid($user, $data['password'])) {
            throw $this->createAccessDeniedException('Invalid credentials.');
        }

        $token = $jwtEncoder->encode([
            'sub' => $user->getId(),
            'exp' => time() + 3600 // задайте время жизни токена по вашему усмотрению
        ]);

        return new JsonResponse(['token' => $token]);
    }

    /**
     * @Route("/api/token/refresh", name="api_token_refresh", methods={"POST"})
     */
    public function refreshToken(Request $request, JWTEncoderInterface $jwtEncoder)
    {
        $token = $request->headers->get('Authorization');

        if (!$token) {
            throw $this->createAccessDeniedException('Token not found.');
        }

        try {
            $decodedToken = $jwtEncoder->decode($token);
        } catch (Exception $e) {
            throw $this->createAccessDeniedException('Invalid token.');
        }

        $token = $jwtEncoder->encode([
            'sub' => $decodedToken['sub'],
            'exp' => time() + 3600 // задайте время жизни токена по вашему усмотрению
        ]);

        return new JsonResponse(['token' => $token]);
    }
}

В этих методах мы принимаем запросы от клиента, аутентифицируем пользователя, используя встроенные функции Symfony, и генерируем токены JWT с помощью JWTEncoderInterface.

Обратите внимание, что вы должны настроить роуты и ограничения доступа к контроллерам, чтобы они были доступны только методам POST и только аутентифицированным пользователям.

Шаг 4: Настройка Guard Authenticator

Откройте файл config/packages/security.yaml и настройте Guard Authenticator следующим образом:

security:
    firewalls:
        api:
            pattern: ^/api
            stateless: true
            anonymous: true
            provider: app_user_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

    providers:
        app_user_provider:
            entity:
                class: AppEntityUser
                property: email

Этот конфигурационный файл говорит Symfony использовать lexik_jwt_authentication.jwt_token_authenticator в качестве аутентификатора для роутов, начинающихся с /api. Мы также указываем, что пользователи будут храниться в базе данных, и используем свойство email в качестве идентификатора.

Шаг 5: Тестирование

Теперь ваше REST API с аутентификацией готово к тестированию. Вы можете использовать различные инструменты, такие как Postman или curl, чтобы отправлять запросы на /api/login и /api/token/refresh, предоставляя необходимые данные пользователя.

После успешной аутентификации вы получите токен JWT, который может быть использован для последующих запросов к защищенным роутам в вашем REST API. Вы также можете использовать lexik_jwt_authentication.encoder для декодирования токена и получения данных пользователя.

В итоге, создание REST API аутентификации на Symfony с использованием пакета "LexikJWTAuthenticationBundle" состоит из нескольких шагов: установка зависимостей, конфигурация пакета, создание контроллера аутентификации, настройка Guard Authenticator и, наконец, тестирование вашего API. Этот подробный ответ поможет вам в реализации аутентификации в вашем REST API на Symfony.