You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 08:35:03