如何使用 Symfony 4 中的 fos 用户将用户迁移到新的密码哈希算法?
How to Migrate users to new password hashing algorithms with fos user in Symfony 4?
我有一个带有 fos 用户的旧 Symfony 2 应用程序,其中包含使用 sha512 算法编码的密码。
我希望在将 table 用户迁移到具有 fos 用户 2.1 的新应用程序 symfony 4 之后,当用户使用侦听器登录时能够使用算法 bcrypt 修改密码。
在 Symfony 下可以有多个编码器,但问题是我们不能用不同的算法复制相同的编码器,例如:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
FOS\UserBundle\Model\UserInterface: bcrypt
或使用此代码,我收到此错误消息:
Unrecognized option "FOS\UserBundle\Model\UserInterface" under "security.encoders.old"
encoders:
old:
FOS\UserBundle\Model\UserInterface:
algorithm: sha512
new:
FOS\UserBundle\Model\UserInterface:
algorithm: bcrypt
更新到已发布的 Symfony 4.4 earlier this week。
4.4 支持 Password Migrations。
将您的编码器声明为 "auto",这样 Symfony 将始终为新密码选择最好的编码器,并为旧密码选择合适的编码器:
encoders:
FOS\UserBundle\Model\UserInterface:
algorithm: auto
cost: 14
然后让你的 UserRepository
实现 PasswordUpgraderInterface
。此接口包含一个方法 upgradePassword()
,每当需要将哈希升级到更新的算法时调用该方法。
文档中的示例实现如下:
// ...
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
class UserRepository extends EntityRepository implements PasswordUpgraderInterface
{
// ...
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
{
// this code is only an example; the exact code will depend on
// your own application needs
$user->setPassword($newEncodedPassword);
$this->getEntityManager()->flush($user);
}
}
根据您的用例进行调整,当用户登录到您的应用程序时,您将能够透明地将您的密码哈希更新为最新的哈希算法。
由于现代散列算法将散列存储在与散列密码相同的字段上,如果您的旧散列机制依赖于单独的散列字段,您可以在此过程中将其设置为 null,因为它不再需要。
这项新功能的好消息。
所以我迁移到4.4版本。
我更改了 Fos User 的自定义用户提供程序:
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
public function upgradePassword(SecurityUserInterface $user, string $newEncodedPassword): void
{
// set the new encoded password on the User object
$user->setPassword($newEncodedPassword);
//you can set salt to null because the new encoders use algorithms without the salt
$user->setSalt(null);
// store the new password
$this->userManager->updateUser($user);
}
这很有效!
但是 Fos 用户包有一个问题,当用户修改他的密码时,这会创建一个未使用的新盐。最主要的是它有效。
我有一个带有 fos 用户的旧 Symfony 2 应用程序,其中包含使用 sha512 算法编码的密码。
我希望在将 table 用户迁移到具有 fos 用户 2.1 的新应用程序 symfony 4 之后,当用户使用侦听器登录时能够使用算法 bcrypt 修改密码。
在 Symfony 下可以有多个编码器,但问题是我们不能用不同的算法复制相同的编码器,例如:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
FOS\UserBundle\Model\UserInterface: bcrypt
或使用此代码,我收到此错误消息:
Unrecognized option "FOS\UserBundle\Model\UserInterface" under "security.encoders.old"
encoders:
old:
FOS\UserBundle\Model\UserInterface:
algorithm: sha512
new:
FOS\UserBundle\Model\UserInterface:
algorithm: bcrypt
更新到已发布的 Symfony 4.4 earlier this week。
4.4 支持 Password Migrations。
将您的编码器声明为 "auto",这样 Symfony 将始终为新密码选择最好的编码器,并为旧密码选择合适的编码器:
encoders:
FOS\UserBundle\Model\UserInterface:
algorithm: auto
cost: 14
然后让你的 UserRepository
实现 PasswordUpgraderInterface
。此接口包含一个方法 upgradePassword()
,每当需要将哈希升级到更新的算法时调用该方法。
文档中的示例实现如下:
// ...
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
class UserRepository extends EntityRepository implements PasswordUpgraderInterface
{
// ...
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
{
// this code is only an example; the exact code will depend on
// your own application needs
$user->setPassword($newEncodedPassword);
$this->getEntityManager()->flush($user);
}
}
根据您的用例进行调整,当用户登录到您的应用程序时,您将能够透明地将您的密码哈希更新为最新的哈希算法。
由于现代散列算法将散列存储在与散列密码相同的字段上,如果您的旧散列机制依赖于单独的散列字段,您可以在此过程中将其设置为 null,因为它不再需要。
这项新功能的好消息。 所以我迁移到4.4版本。
我更改了 Fos User 的自定义用户提供程序:
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
public function upgradePassword(SecurityUserInterface $user, string $newEncodedPassword): void
{
// set the new encoded password on the User object
$user->setPassword($newEncodedPassword);
//you can set salt to null because the new encoders use algorithms without the salt
$user->setSalt(null);
// store the new password
$this->userManager->updateUser($user);
}
这很有效!
但是 Fos 用户包有一个问题,当用户修改他的密码时,这会创建一个未使用的新盐。最主要的是它有效。