Symfony6升级后登录成功但app.user为空:重定向后令牌丢失
Symfony 6.2 升级后认证令牌丢失问题
问题现象
Symfony 5.3应用升级至6.2后,登录成功重定向后app.user始终为null,Twig模板调用app.user.username时抛出**无法访问null变量的属性'username'**错误,核心原因是重定向后认证令牌丢失。
相关代码片段
security.yaml
security: providers: database_users: id: App\Security\UsersProvider password_hashers: App\Entity\Users: algorithm: sha512 firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: lazy: true provider: database_users logout: path: logout target: /login invalidate_session: true custom_authenticators: - App\Security\LoginFormAuthentificator
LoginFormAuthentificator 关键代码
class LoginFormAuthentificator extends AbstractLoginFormAuthenticator { use TargetPathTrait; public const LOGIN_ROUTE = 'login'; private $entityManager; private $urlGenerator; private $csrfTokenManager; private $userProvider; public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserProviderInterface $userProvider) { $this->entityManager = $entityManager; $this->urlGenerator = $urlGenerator; $this->csrfTokenManager = $csrfTokenManager; $this->userProvider = $userProvider; } public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response { if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } return new RedirectResponse($this->urlGenerator->generate('researchGeneral')); } public function authenticate(Request $request): \Symfony\Component\Security\Http\Authenticator\Passport\Passport { $encoder = new MessageDigestPasswordHasher('sha512', true, 5000); $user = $this->userProvider->loadUserByUsername($request->request->get("username")); if (!$user) { throw new CustomUserMessageAuthenticationException('Invalid credentials.'); } $verif = $encoder->verify($user->getPassword(), $request->request->get("password"), 'sha512'); if (!$verif) { throw new CustomUserMessageAuthenticationException('Invalid credentials.'); } return new SelfValidatingPassport(new UserBadge($request->request->get("username"))); } }
SecurityController 关键代码
class SecurityController extends AbstractController { /** * @Route("/login", name="login") */ public function login(AuthenticationUtils $authenticationUtils): Response { if ($this->getUser()) { return $this->redirectToRoute('researchGeneral'); } $error = $authenticationUtils->getLastAuthenticationError(); $lastUsername = $authenticationUtils->getLastUsername(); return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]); } }
问题根源与修复方案
1. 自定义认证器的核心错误
authenticate方法中手动处理密码验证,且返回的SelfValidatingPassport未关联已加载的用户对象,导致Symfony无法正确生成并持久化认证令牌。
修复后的authenticate方法
use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; public function authenticate(Request $request): Passport { $username = $request->request->get('username'); $password = $request->request->get('password'); return new Passport( new UserBadge($username, function($userIdentifier) { return $this->userProvider->loadUserByUsername($userIdentifier); }), new PasswordCredentials($password) ); }
2. 移除冗余代码
删除原authenticate方法中手动实例化MessageDigestPasswordHasher和密码验证的逻辑,Symfony会自动使用security.yaml中配置的password_hashers完成验证。
3. 验证用户实体接口
确保App\Entity\Users类实现Symfony\Component\Security\Core\User\UserInterface,并正确实现getUsername()、getPassword()等必填方法。
内容的提问来源于stack exchange,提问作者E Epsylon
相关产品推荐
相关产品推荐

