Symfony 5.3 TEST/PROD环境下链式用户提供器部分账号登录失败排查
排查步骤
- 优先核验两个用户实体的序列化实现
非DEV环境下Symfony对会话存储的用户对象反序列化校验更严格。检查App\Entity\WebUser和App\Entity\Security\User是否都正确实现了Symfony\Component\Security\Core\User\UserInterface的所有方法,尤其是serialize()、unserialize()或者__serialize()、__unserialize()(对应不同PHP版本),有没有遗漏用户标识字段、角色字段。也可以在refreshUser方法中加日志,确认登录成功后下一次请求加载用户时,是否出现反序列化失败返回空的情况,这种情况会直接导致令牌失效,跳转回登录页。 - 检查链式用户提供器的刷新逻辑
链式提供器会按配置顺序依次调用子提供器的refreshUser方法,只有前一个提供器抛出UsernameNotFoundException时才会轮到下一个提供器。确认其中登录失败的用户类,在app_user_provider中查询不到时是否正确抛出了对应异常,没有提前返回空或者其他异常导致链式查询中断。DEV环境下的调试容错机制可能会忽略这类异常,非DEV环境会直接判定用户加载失败。 - 核对环境差异化配置
不要只核对.env文件,还要检查config/packages/test/、config/packages/prod/目录下有没有独立的security.yaml、framework.yaml配置覆盖了全局配置:- 确认TEST/PROD环境下的防火墙没有被误设为
stateless: true - 核对会话cookie配置:如果TEST/PROD配置了
cookie_secure: auto或true,但你用HTTP协议访问站点,会导致会话cookie无法写入,看起来就是登录成功后没有会话,跳转回登录页 - 确认两个环境的用户密码哈希算法配置没有差异
- 确认TEST/PROD环境下的防火墙没有被误设为
- 开启TEST环境安全调试日志
在config/packages/test/security.yaml中添加如下配置,将安全组件日志级别调至DEBUG:
复现登录问题后查看日志,搜索security: firewalls: main: log_statistics: true monolog: handlers: main: level: debugdeauthenticated、user not found、refresh failed关键字,就能定位到令牌失效的具体原因。 - 校验用户角色返回格式
确认两类用户的getRoles()方法返回的都是非空的字符串数组,没有返回null、空值或者非数组格式,非DEV环境下角色格式错误会直接判定令牌无效。
内容的提问来源于stack exchange,提问作者Pep
相关产品推荐
相关产品推荐

