Не удается получить токен Lexik JWT из другого домена

Симфония 4

Сделал авторизацию lexik jwt по инструкции:

https://h-benkachoud.medium.com/symfony-rest-api-without-fosrestbundle-using-jwt-authentication-part-2-be394d0924dd

Он отлично работает с почтальоном или консольным завитком. Когда я пытаюсь получить токен по запросу ajax (из другого домена), у меня стандартная ошибка

В запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

Я пытаюсь исправить это связкой nelmio_cors

НО

Если я беру токен почтальоном или консольным curl - отладчик даже не заходит в контроллер, а я получаю токен (даже не знаю как).

Если я пытаюсь взять токен по ajax-запросу (из другого домена) ПОСЛЕ установки nelmio - я попадаю в контроллер: App\Controller\AuthController::getTokenUser

А у меня ошибка 500

Невозможно автоматически связать аргумент $user из App\Controller\AuthController::getTokenUser(): он ссылается на интерфейс Symfony\Component\Security\Core\User\UserInterface, но такой службы не существует. Вы создали класс, который реализует этот интерфейс?

Я не понимаю, почему с nelmio_cors запрос из другого домена попадает в контроллер, а без nelmio_cors не попадает... Как это исправить?

Мне нужно получить токен по http-запросу с другого домена

безопасность.yaml

    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    encoders:
        App\Entity\User:
            algorithm: bcrypt


    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: username

    firewalls:

        login:
            pattern:  ^/api/login
            stateless: true
            anonymous: true
            json_login:
                provider: app_user_provider
                check_path:               /api/login_check
                success_handler:          lexik_jwt_authentication.handler.authentication_success
                failure_handler:          lexik_jwt_authentication.handler.authentication_failure
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/login_check, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/test,       roles: IS_AUTHENTICATED_FULLY }

маршрутизатор:

api_login_check:
  path: /api/login_check
  controller: App\Controller\AuthController::getTokenUser

Аутконтроллер:

<?php

namespace App\Controller;

use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\User\UserInterface;

class AuthController extends ApiController
{

    /**
     * @param UserInterface $user
     * @param JWTTokenManagerInterface $JWTManager
     * @return JsonResponse
     */
    public function getTokenUser(UserInterface $user, JWTTokenManagerInterface $JWTManager)
    {
        return new JsonResponse(['token' => $JWTManager->create($user)]);
    }
}

nelmio_cors.yaml:

nelmio_cors:
    defaults:
        origin_regex: true
        allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
        allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
        allow_headers: ['Content-Type', 'Authorization']
        expose_headers: ['Link']
        max_age: 3600
    paths:
        '^/': null

CORS_ALLOW_ORIGIN='^.*$'

.htaccess:

RewriteEngine On
Options +FollowSymlinks
RewriteBase /

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [L]

Помогите, пожалуйста


person Den    schedule 28.05.2021    source источник


Ответы (1)


Ваша проблема (вероятно) связана с частью UserInterface $user вашего контроллера. Вместо этого попробуйте внедрить Security $security, а затем получить пользовательский объект из $security.

<?php

namespace App\Controller;

use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\Security;

class AuthController extends ApiController
{

    /**
     * @param Security $security
     * @param JWTTokenManagerInterface $JWTManager
     * @return JsonResponse
     */
    public function getTokenUser(Security $security, JWTTokenManagerInterface $JWTManager): JsonResponse
    {
        return new JsonResponse(['token' => $JWTManager->create($security->getUser())]);
    }
}

Поскольку вы не можете автоматически подключить текущего пользователя в Symfony

person wawa    schedule 29.05.2021
comment
Спасибо, но $security-›getUser() берет пользователя из готового токена. Я еще не авторизован и у меня нет токена. Как аутентифицироваться в контроллере? - person Den; 31.05.2021
comment
Я в замешательстве, если вы еще не вошли в систему, как вы думаете, как Symfony узнает, какого пользователя вы хотите загрузить? - person wawa; 31.05.2021