Как добавить возможность аутентификации в Swagger/OpenAPI в Symfony?

Вопрос или проблема

Я создаю несколько простых конечных точек API в Symfony с использованием API Platform (я не фанат этого, но он уже используется, поэтому не хочу изобретать велосипед).
Что я пытаюсь сделать, так это настроить эту форму авторизации:
вставьте описание изображения здесь

Поэтому вместо ключа API я хочу добавить поля для имени пользователя и пароля, Swagger отправит их на мой собственный конечный пункт аутентификации API, и возвращенный токен будет прикреплен к запросам.

Согласно определенным источникам и chatGPT, это можно сделать с помощью пакета nelmio api doc.
Вот шаги, которые я попробовал до сих пор:
установил пакет api platform
установил пакет nelmio api doc
сгенерировал секретные ключи

Это конфигурация пакета api_platform.yaml

api_platform:

    title: 'Statistics API'

    version: '2.0'

    mapping:
        paths: ['%kernel.project_dir%/src/Entity']
    # Включить документацию и экспорт Swagger.
    enable_swagger: true

    enable_nelmio_api_doc: true

    # Включить Swagger ui.
    enable_swagger_ui: true

    # Включить точку входа.
    enable_entrypoint: true

    # Включить документацию.
    enable_docs: true

    collection:
        pagination:
            enabled: true
            items_per_page: 500

    formats:
          json:
              mime_types: ['application/json']
          html:
              mime_types: ['text/html']

    swagger:
        api_keys:
            apiKey:
                name: Authorization
                type: query

Это конфигурация маршрутов api_platform.yaml

api_platform_back:
    resource: .
    type: api_platform
    prefix: /api

Вот конфигурация пакета nelmio_api_doc.yaml

nelmio_api_doc:
    documentation:
        info:
            title: My App
            description: Это отличное приложение!
            version: 1.0.0
        components:
            securitySchemes:
                bearerAuth:
                    type: http
                    scheme: bearer
                    bearerFormat: JWT
        security:
            - bearerAuth: []
    areas: # для фильтрации задокументированных областей
        path_patterns:
            - ^/api(?!/doc$) # Принимает маршруты под /api, за исключением /api/doc

Конфигурация маршрутов nelmio_api_doc.yaml

# Поделитесь своей документацией в формате JSON, совместимом со swagger
app.swagger:
    path: /api/doc.json
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger }

## Требуется компонент Asset и пакет Twig
## $ composer require twig asset
app.swagger_ui:
   path: /api
   methods: GET
   defaults: { _controller: nelmio_api_doc.controller.swagger_ui }

API файрволы из security.yaml

api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: app_user_provider
            jwt: ~
        api_login:
            pattern: ^/api-login
            stateless: true

И метод контроллера, который должен обрабатывать аутентификацию:

/**
     * @Route("/api-login", name="api_login", methods={"POST"})
     *
     * @OA\Post(
     *     path="/api-login",
     *     summary="Аутентификация пользователя и получение JWT токена",
     *     tags={"Authentication"},
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="email", type="string"),
     *             @OA\Property(property="password", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Токен сгенерирован",
     *         @OA\JsonContent(
     *             type="object",
     *             @OA\Property(property="token", type="string")
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Неверные учетные данные"
     *     )
     * )
     * @Security(name="Bearer")
     */
    public function apiLogin(Request $request): JsonResponse
    {
        //Некоторая логика находится здесь
    }

Конечная точка входа работает нормально, если я делаю запрос, он возвращает токен. Но похоже, что аннотация над методом вообще не влияет. Честно говоря, я не совсем уверен, что то, что я намерен сделать, действительно осуществимо, потому что документация не очень ясна, и мои изменения основаны на концепциях, предложенных (но не доказанных) другими.

Я также попробовал этот Добавление документации по аутентификации в Swagger в NelmioApiDocBundle и добавил свойство path в документацию, но ничего не произошло.
Буду признателен за любую помощь, спасибо.

Ответ или решение

Чтобы добавить возможность аутентификации в Swagger/OpenAPI в Symfony, вам необходимо настроить несколько компонентов: NelmioApiDocBundle для документации вашей API и механизм аутентификации, например, JWT. Ваша текущая настройка выглядит неплохо, но давайте более подробно разберем необходимые шаги и исправления для достижения вашей цели.

Шаги для настройки аутентификации в Swagger (OpenAPI) с использованием NelmioApiDocBundle в Symfony

1. Убедитесь, что зависимости установлены

Проверьте, что у вас установлены следующие пакеты:

composer require nelmio/api-doc-bundle
composer require lexik/jwt-authentication-bundle

Это обеспечит необходимую функциональность для создания и отображения документации вашей API и для реализации аутентификации с использованием JWT.

2. Настройка выполнения аутентификации

Убедитесь, что ваш контроллер для аутентификации правильно реализован. Вы уже сделали это в вашем apiLogin методе. Но помните, что важно, чтобы путь аутентификации /api-login был доступен для анонимных пользователей (в вашем случае api_login).

3. Настройка security.yaml

В вашем security.yaml файле проверьте, что настройка для вашего API выглядит следующим образом:

firewalls:
    api:
        pattern: ^/api
        stateless: true
        anonymous: false
        provider: app_user_provider
        jwt: ~
    api_login:
        pattern: ^/api-login$
        stateless: true
        anonymous: true

Это позволит открытый доступ к маршруту /api-login для анонимных пользователей, а все остальные маршруты будут защищены.

4. Конфигурация файлов api_platform.yaml и nelmio_api_doc.yaml

Ваш api_platform.yaml файл выглядит в целом правильно, однако подправьте конфигурацию swagger для обработки аутентификации. Обновленный раздел должен включать:

swagger:
    security:
        - bearerAuth: []

Ваш nelmio_api_doc.yaml тоже нужно будет подправить для добавления схемы безопасности. Убедитесь, что securitySchemes правильно настроено:

nelmio_api_doc:
    documentation:
        ...
        components:
            securitySchemes:
                bearerAuth:
                    type: http
                    scheme: bearer
                    bearerFormat: JWT
        security:
            - bearerAuth: []
    ...

Это обеспечит отображение UI аутентификации Bearer Token в Swagger UI.

5. Обновление аннотаций в контроллере

Ваш метод apiLogin правильно аннотирован, но убедитесь, что он действительно находит @Security(name="Bearer"), даже если данный элемент не является обязательным. Лучше использовать простую аннотацию @OA\SecurityScheme в верхней части файла контроллера или в конфигурации nelmio_api_doc.yaml.

Пример обновленной аннотации может выглядеть так:

/**
 * @OA\Post(
 *     path="/api-login",
 *     summary="Authenticate user and get a JWT token",
 *     tags={"Authentication"},
 *     @OA\RequestBody(
 *         required=true,
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="email", type="string"),
 *             @OA\Property(property="password", type="string")
 *         )
 *     ),
 *     @OA\Response(
 *         response=200,
 *         description="Token generated",
 *         @OA\JsonContent(
 *             type="object",
 *             @OA\Property(property="token", type="string")
 *         )
 *     ),
 *     @OA\Response(
 *         response=401,
 *         description="Invalid credentials"
 *     ),
 *     security={{"bearerAuth": {}}}
 * )
 */

6. Проверка и тестирование

После выполнения всех вышеуказанных шагов выполните команду:

php bin/console cache:clear

Затем протестируйте свой API, зайдя на /api и имея возможность вставлять полученный JWT токен в поле аутентификации.

Заключение

Следуя этим шагам, вы должны успешно интегрировать аутентификацию через JWT в интерфейс Swagger вашей API. Если у вас остались дополнительные вопросы или вам требуется помощь с конкретными ошибками, будьте уверены, что сообщество всегда готово помочь.

Оцените материал
Добавить комментарий

Капча загружается...