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

Symfony 5.4升级后登录更新lastLogin触发username非空约束错误

问题:Symfony升级5.4后FOSUserBundle更新lastLogin时出现字段非空错误

我使用FOSUserBundle进行身份验证,登录成功获取访问令牌后,同一请求中触发安全事件更新用户表lastLogin字段时,抛出SQL错误:Integrity constraint violation: 1048 Column 'username' cannot be null。该问题是将Symfony从4.3版本升级到5.4版本后出现的。


Security配置文件

security:
    password_hashers:
        FOS\UserBundle\Model\UserInterface:
            algorithm: auto
            cost: 13

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            user_checker: security.user_checker
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
            logout:       true
            anonymous:    true
            remember_me:
                secret:   '%kernel.secret%'
                lifetime: 604800 # 1 week in seconds
                path:     /


    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: '%env(X-FORWARDED-PROTO)' }
        ......


    imports:
    - { resource: 'role_hierarchy.yaml' }

已安装的Composer依赖

{
    "doctrine/doctrine-bundle": "2.7.2",
    "doctrine/doctrine-migrations-bundle": "3.2.4",
    "doctrine/orm": "2.15.3",
    "friendsofsymfony/user-bundle": "3.2.1"
}

问题原因及解决方法

1. 核心原因

Symfony 5.4调整了安全事件的生命周期和用户对象的序列化逻辑,而FOSUserBundle 3.2.1与该版本的兼容性不足,导致更新lastLogin时用户对象的username字段被意外置空。

2. 具体解决步骤

(1)替换用户提供者

将security配置中的用户提供者从fos_user.user_provider.username改为fos_user.user_provider.username_email,该提供者在处理用户对象时更稳定,可避免字段丢失:

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

(2)升级FOSUserBundle版本

FOSUserBundle 3.2.1对Symfony 5.4的支持不完善,建议升级到3.3.0及以上的稳定版,修复兼容性问题:

composer require friendsofsymfony/user-bundle:^3.3

(3)检查用户实体映射

确认你的用户实体中username字段的Doctrine映射未被错误设置为允许空值,同时验证实体类的getUsername()/setUsername()方法逻辑正常,无值丢失情况。

(4)手动处理lastLogin更新(备选方案)

如果上述方法无效,可在登录成功事件中手动更新lastLogin,绕过FOSUserBundle的自动处理:

// src/EventListener/LoginSuccessListener.php
namespace App\EventListener;

use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class LoginSuccessListener
{
    private $userManager;

    public function __construct(UserManagerInterface $userManager)
    {
        $this->userManager = $userManager;
    }

    public function onInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();
        if ($user instanceof \FOS\UserBundle\Model\UserInterface) {
            $user->setLastLogin(new \DateTime());
            $this->userManager->updateUser($user);
        }
    }
}

在services.yaml中注册监听:

App\EventListener\LoginSuccessListener:
    tags:
        - { name: kernel.event_listener, event: security.interactive_login }

内容的提问来源于stack exchange,提问作者kenan ismail

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:12:00