无法从其他域获取 Lexik JWT 令牌

问题描述

Symfony 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 获取令牌 - 调试器甚至不会进入控制器,我会得到令牌(我什至不知道如何)。

如果我在安装 nelmio 后尝试通过 ajax 请求(来自其他域)获取令牌 - 我进入控制器:App\Controller\AuthController::getTokenUser

我有一个 500 错误

不能自动装配参数 $user of “App\Controller\AuthController::getTokenUser()”:它引用 界面“Symfony\Component\Security\Core\User\UserInterface”但没有 存在这样的服务。您是否创建了一个实现此功能的类 界面?

我不明白为什么来自其他域的 nelmio_cors 请求会到达控制器,而没有 nelmio_cors 则不会... 如何解决

我需要通过来自其他域的 http 请求获得令牌

security.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]

请帮忙

解决方法

您的问题(可能)与控制器的 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 中自动连接当前用户