Symfony3.4开启logout_on_user_change时单元测试登录失败问题
解决Symfony 4中
logout_on_user_change导致单元测试登录失败的问题 我之前也碰到过一模一样的问题:把logout_on_user_change设为true(Symfony 4默认就是这个配置)后,开发环境里登录、登出啥的都正常,但跑单元测试的时候,登录认证总是失败,折腾了好一阵才找到根源——后台的用户操作触发了这个自动登出机制,而问题出在用户实体的serialize()和isEqualTo()方法的字段不匹配上。
问题原因
当logout_on_user_change开启时,Symfony会在每次请求时对比会话中序列化的用户数据,和从数据库加载的用户对象是否一致。如果isEqualTo()方法校验的字段,和serialize()里序列化的字段不一样,就会被判定为用户信息变更,触发自动登出,这在单元测试场景下就会导致认证失败。
解决方案
核心就是确保isEqualTo()方法里校验的所有字段,和serialize()函数中序列化的字段完全一致,不能有遗漏也不能多出来。下面是我调整后的正确代码示例:
/** * @see \Serializable::serialize() */ public function serialize() { return serialize( array( $this->id, $this->email, $this->password, $this->salt ) ); } /** * @see \Serializable::unserialize() */ public function unserialize($serialized) { list ( $this->id, $this->email, $this->password, $this->salt ) = unserialize($serialized, ['allowed_classes' => false]); } public function isEqualTo(UserInterface $user) { if ($this->id !== $user->getId()) { return false; } if ($this->password !== $user->getPassword()) { return false; } if ($this->salt !== $user->getSalt()) { return false; } if ($this->email !== $user->getEmail()) { return false; } return true; }
你可以看到,serialize()里序列化了id、email、password、salt这四个字段,对应的isEqualTo()也逐一校验了这四个字段,这样就能保证用户对象的一致性校验准确,不会在单元测试里误触发自动登出了。
内容的提问来源于stack exchange,提问作者Pointi
相关产品推荐
相关产品推荐

