Symfony4跨域请求无法获取Lexik JWT令牌报错该如何解决
问题原因说明
- 未安装nelmio_cors时Postman/curl请求不会进入自定义控制器的原因:你在
security.yaml中配置了json_login使用LexikJWT自带的成功/失败处理器,安全层的登录监听器会在控制器执行前就完成身份校验,直接返回令牌,根本不会触发你绑定的getTokenUser控制器。跨域请求时浏览器会先发送OPTIONS预检请求,未配置CORS时预检请求直接被拦截返回无CORS头的错误,所以POST请求不会到后端。 - 安装nelmio_cors后出现500错误的原因:nelmio_cors处理了OPTIONS预检请求,让后续POST请求可以进入业务流程,但你在控制器中直接注入
UserInterface是错误用法,Symfony的自动装配无法直接注入当前登录用户,因此抛出自动装配失败的异常。
修复步骤
方案一(推荐,复用LexikJWT自带逻辑)
你完全不需要自定义控制器处理登录校验逻辑,现有代码里的AuthController::getTokenUser属于冗余配置,直接删除相关配置即可:
- 修改路由配置,删除
api_login_check绑定的自定义控制器:
# 路由配置 api_login_check: path: /api/login_check
- 修正
security.yaml中login防火墙配置,放行OPTIONS请求:
firewalls: login: pattern: ^/api/login stateless: true anonymous: true methods: [POST, OPTIONS] # 新增这行,放行预检请求 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
- 调整
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规则
- 执行缓存清理命令生效:
php bin/console cache:clear
方案二(需要自定义令牌返回逻辑时使用)
如果你确实需要自定义登录成功后的返回内容,保留自定义控制器的话,按以下步骤修改:
- 删除
security.yaml中json_login下的success_handler、failure_handler配置,让请求进入自定义控制器。 - 修改
AuthController代码,正确获取当前登录用户:
<?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 { public function getTokenUser(Security $security, JWTTokenManagerInterface $JWTManager): JsonResponse { $user = $security->getUser(); if (null === $user) { return new JsonResponse(['message' => '登录凭证无效'], 401); } return new JsonResponse(['token' => $JWTManager->create($user)]); } }
- 保留方案一中的防火墙、nelmio_cors配置修改,清理缓存即可。
内容的提问来源于stack exchange,提问作者Den
相关产品推荐
相关产品推荐

