Symfony 6.1自动装配PasswordHasherInterface报错排查
自动装配报错的根本原因
你当前的services.yaml配置没有问题,报错核心原因是注入的Symfony\Component\PasswordHasher\PasswordHasherInterface在Symfony 6.1的服务容器中没有默认绑定的可注入实现,自动装配无法找到对应服务。
这个接口是底层单个密码哈希器的通用契约,框架不会直接将它注册为可自动装配的服务——Symfony支持为不同的用户实体配置不同的哈希算法,容器里可能同时存在多个该接口的实现,无法仅根据接口类型自动判定要注入哪一个。
Symfony 6.1 哈希明文密码的正确方式
按使用场景分两种处理方案:
场景1:给用户实体哈希登录密码(适配你当前编写Fixtures的场景)
直接注入框架预置的、可自动装配的Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface服务,调用其hashPassword()方法即可。该方法会自动读取security.yaml中为对应用户类配置的哈希规则生成合规哈希值,不需要手动指定算法参数。
修改后的UserFixture参考代码如下:
<?php namespace App\DataFixtures; use App\Model\User\Entity\User\Email; use App\Model\User\Entity\User\Id; use App\Model\User\Entity\User\Role; use App\Model\User\Entity\User\User; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; class UserFixture extends Fixture { private UserPasswordHasherInterface $hasher; public function __construct(UserPasswordHasherInterface $hasher) { $this->hasher = $hasher; } public function load(ObjectManager $manager): void { // 先实例化用户对象,哈希时需要传入用户实例匹配对应的哈希规则 $user = User::signUpByEmail( Id::next(), new \DateTimeImmutable(), new Email("admin@app.test"), "", // 占位即可,后续替换为真实哈希 "token" ); // 传入用户实例与明文密码生成哈希 $hash = $this->hasher->hashPassword($user, "password"); // 按你自己的User实体逻辑设置密码哈希,若signUpByEmail支持直接传哈希可调整实例化顺序 $user->setPassword($hash); $user->confirmSignUp(); $user->changeRole(Role::admin()); $manager->persist($user); $manager->flush(); } }
注意:hashPassword()第一个参数必须传入实现了PasswordAuthenticatedUserInterface的用户实体实例,框架依靠这个实例的类名匹配对应的哈希配置,不可传空或其他类型值。
场景2:与用户实体无关的通用字符串哈希
如果不需要关联用户实体,仅需要对任意字符串做密码级哈希,可以注入Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface服务,通过工厂获取指定配置的哈希器后再执行哈希操作:
// 获取security配置中默认算法对应的哈希器 $hasher = $passwordHasherFactory->getPasswordHasher('auto'); $hash = $hasher->hash('待哈希的明文字符串');
内容的提问来源于stack exchange,提问作者F. Tomas

