Symfony 6.3 Linkedin登录生成JWT令牌无效问题求助
问题:LinkedIn OAuth生成的JWT令牌无效,返回401错误
问题详情
已完成以下操作:
- 成功获取LinkedIn用户数据
- 创建User对象并注入用户信息
- 将用户数据持久化到数据库
- 生成JWT令牌:
$jwtToken = $this->jwtManager->create($userEntity);
但使用该令牌访问接口时,返回401错误:
{ "code": 401, "message": "Invalid credentials." }
直接调用Security的/api/login_check接口时,认证正常,返回:
{ "message": "Welcome to your new controller!", "path": "src/Controller/DashboardController.php" }
已尝试的解决方案(均未生效)
- 调用
return $security->login($userEntity, 'json_login', 'login');,其中"login"是JWT使用的防火墙,"json_login"是认证器 - 调用
return $authenticationSuccessHandler->handleAuthenticationSuccess($user);
补充说明:$userEntity包含正确的用户信息,生成的JWT令牌也包含所有用户详情。接口响应中已返回令牌,但将其放入Bearer Token中使用时仍然无效。
已安装的Bundle
"php": ">=8.1", "ext-ctype": "*", "ext-iconv": "*", "doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.16", "friendsofsymfony/rest-bundle": "^3.6", "jms/serializer-bundle": "^5.3", "league/oauth2-linkedin": "^5.1", "lexik/jwt-authentication-bundle": "*", "symfony/console": "6.3.*", "symfony/dotenv": "6.3.*", "symfony/flex": "^2", "symfony/framework-bundle": "6.3.*", "symfony/runtime": "6.3.*", "symfony/yaml": "6.3.*"
Security配置
security: enable_authenticator_manager: true password_hashers: App\Entity\User: 'auto' Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: 'auto' cost: 15 providers: app_user_provider: entity: class: App\Entity\User property: email firewalls: login: pattern: ^/api/login stateless: true json_login: check_path: /api/login_check success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure api: pattern: ^/api stateless: true jwt: ~ dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: lazy: true provider: app_user_provider access_control: - { path: ^/api/register, roles: PUBLIC_ACCESS } - { path: ^/api/login, roles: PUBLIC_ACCESS } - { path: ^/api/auth/linkedin, roles: PUBLIC_ACCESS } - { path: ^/api/li-callback, roles: PUBLIC_ACCESS } - { path: ^/api, roles: IS_AUTHENTICATED_FULLY } when@test: security: password_hashers: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: auto cost: 4 # Lowest possible value for bcrypt time_cost: 3 # Lowest possible value for argon memory_cost: 10 # Lowest possible value for argon
控制器代码
<?php // src/Controller/LinkedinAuthController.php namespace App\Controller; use App\Entity\User; use Doctrine\ORM\EntityManagerInterface; use App\Service\LinkedinAuthService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use League\OAuth2\Client\Provider\Linkedin; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; use Symfony\Bundle\SecurityBundle\Security; class LinkedinAuthController extends AbstractController { private $linkedinAuthService; private $entityManager; private $jwtManager; public function __construct(LinkedinAuthService $linkedinAuthService, EntityManagerInterface $entityManager, JWTTokenManagerInterface $jwtManager) { $this->linkedinAuthService = $linkedinAuthService; $this->entityManager = $entityManager; $this->jwtManager = $jwtManager; } /** * @Route("/api/auth/linkedin", name="api_auth_linkedin") */ public function redirectToLinkedin(): Response // public function redirectToLinkedin(): JsonResponse {...} /** * @Route("/api/li-callback", name="api_linkedin_callback") */ public function linkedinCallback(Request $request, Security $security): JsonResponse { session_start(); if (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { unset($_SESSION['oauth2state']); return new JsonResponse(['error' => 'Invalid state'], 401); } try { $linkedinUser = $this->linkedinAuthService->getUserData($_GET['code']); $userEntity = $this->findOrCreateUser($linkedinUser); // Generate JWT Token // $jwtToken = $this->jwtManager->create($userEntity); // you can also log in on a different firewall return $security->login($userEntity, 'json_login', 'login'); } catch (IdentityProviderException $e) { return new JsonResponse(['error' => 'Authentication failed: '.$e->getMessage()], 401); } } }
内容的提问来源于stack exchange,提问作者Thierry Beaucamp
相关产品推荐
相关产品推荐

