我正在构建一个基本的 [电子邮件受保护] 应用程序。
我创建了自己的用户实体,扩展了
Symfony\Component\Security\Core\User\UserInterface
和 PasswordAuthenticatedUserInterface
。
我正在使用 symfony 提供的用户身份验证过程,我不想做任何特别的事情,而是按书本操作。
UserInterface
负责方法eraseCredentials
,它在其文档中说:
删除用户的敏感数据。这很重要,如果在任何情况下 给定点,像明文密码这样的敏感信息是 存储在该对象上。
我的用户实体将其密码存储为通过 symfony 的密码哈希器进行哈希处理的密码,如
中所定义security.yaml
:
password_hashers:
App\Entity\User:
algorithm: bcrypt
cost: 12
我仍然觉得我应该实施
eraseCredentials
,一开始,我是这样做的:
#\App\Entity\User
public function eraseCredentials(): void
{
$this->password = null;
}
这会导致奇怪的行为,因为这样我的登录将无法工作,并且我陷入了登录操作的无限循环中。
身份验证非常有效,在调试期间我什至看到我被重定向到正确的
default_target_path
,但是一旦它尝试渲染该页面,这些消息就会在我的dev.log
中弹出:
[2024-09-09T11:03:26.901713+00:00] security.DEBUG: Cannot refresh token because user has changed. {"username":"MY_USER","provider":"Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider"} []
[2024-09-09T11:03:26.902036+00:00] security.DEBUG: Token was deauthenticated after trying to refresh it. [] []
我想我可以将
eraseCredentials
方法留空:
public function eraseCredentials(): void
{
}
现在我可以登录并且该应用程序似乎可以运行。
但我想知道我是否在这里遗漏了一些东西。
这里处理密码管理的预期方法是什么?
/**
* @see UserInterface
*/
public function eraseCredentials(): void
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
请注意,在此示例中,这仅意味着删除
plainPassword
,而不是 password
(纯文本密码,而不是哈希密码)。
如果您没有将纯文本密码存储在用户实体中的任何位置,则可以保留
eraseCredentials()
未实现(正如您已经发现的):
/**
* @see UserInterface
*/
public function eraseCredentials(): void
{}
持久化纯文本密码在相当长一段时间内被认为是一种不好的做法,但是可能在某些情况和设计中,人们可能需要将纯文本密码存储在实体中(而不实际持久化纯文本密码) ).
也许将其传递给其他负责实际哈希密码的服务等。在这种情况下,
eraseCredentials()
将负责确保敏感值在之前被清除,例如,规范化/序列化实体值。