Symfony5.4→6.4:RememberMe功能失效,自动登出问题排查
1. 测试代码语法错误
你的测试方法testAutoLogin中,$handler->createRememberMeCookie($user);语句写在了方法外部,这会导致语法错误,代码无法正确执行。需要将其移到方法内部的$handler实例化之后:
public function testAutoLogin(): void { /** @var User $user */ $user = $this->registerUser(); $handler = new SignatureRememberMeHandler( signatureHasher: static::getContainer()->get(SignatureHasher::class), userProvider: static::getContainer()->get(UserRepository::class), requestStack: $this->createConfiguredMock( RequestStack::class, ['getMainRequest' => $request = new Request()] ), options: [ 'name' => 'REMEMBERME', 'lifetime' => 604800, ], ); // 移到方法内部 $rememberMeCookie = $handler->createRememberMeCookie($user);
2. Cookie值获取方式错误
createRememberMeCookie方法会直接返回生成的Cookie对象,不需要从request attributes中取值。你应该直接使用返回的对象来构造WebDriver的Cookie:
// 替换原有的Cookie创建代码 $cookie = Cookie::createFromArray( [ 'name' => $rememberMeCookie->getName(), 'value' => $rememberMeCookie->getValue(), 'path' => $rememberMeCookie->getPath(), 'domain' => $rememberMeCookie->getDomain(), 'expiry' => $rememberMeCookie->getExpiresTime(), 'secure' => $rememberMeCookie->isSecure(), 'httponly' => $rememberMeCookie->isHttpOnly(), ] );
这样能保证Cookie的所有参数和服务端生成的完全一致,避免手动设置出错。
3. WebDriver初始化语法错误
$driver = $this->createWebDriver;缺少括号,正确写法是:
$driver = $this->createWebDriver();
4. 添加Cookie后未刷新页面
在WebDriver中添加Cookie后,需要刷新当前页面或者重新导航到目标页面,才能让新添加的Cookie生效。否则直接访问MyPage时,请求不会带上刚添加的REMEMBERME Cookie:
$driver->manage()->addCookie($cookie); // 添加刷新操作 $driver->navigate()->refresh(); // 再访问MyPage MyPage::newInstance($this->getRouter(), $driver);
5. 签名属性不匹配
你的remember_me配置中signature_properties为['username', 'password'],但SignatureHasher的构造参数是['getUsername', 'getPassword']。两者需要保持一致:
- 如果实体User使用的是属性名(如
$username),则配置和SignatureHasher都应使用['username', 'password'] - 如果使用的是 getter 方法名,则都应使用
['getUsername', 'getPassword']
修改services.yaml中的参数:
Symfony\Component\Security\Core\Signature\SignatureHasher: factory: ['App\Security\SignatureHasherFactory', 'create'] arguments: - ['username', 'password'] # 和remember_me配置中的signature_properties一致 public: true
6. Secure Cookie设置问题
如果你的测试环境使用HTTP协议,而Cookie设置了secure: true,浏览器不会将该Cookie发送到服务端,导致REMEMBERME Cookie无法被识别。测试环境下可以将secure设置为false,或者确保测试环境使用HTTPS:
// 测试环境下临时修改secure参数 $cookie = Cookie::createFromArray( [ // ...其他参数 'secure' => false, ] );
7. 检查User实体的签名属性
确保User实体的username和password属性在生成签名时是稳定的——比如密码是否是哈希后的字符串(必须是哈希后的,不能是明文),且不会在注册后被意外修改,否则签名验证会失败。
内容的提问来源于stack exchange,提问作者cworain

