期望“Symfony\Component\Security\Core\User\UserInterface”实例作为第一个参数

Cri*_*rro 2 php symfony symfony-security symfony5

我正在尝试为我的用户的密码添加哈希值,我遵循了symfony 5.3 的指南,当我使用

\n
->setPassword($passwordHasher->hashPassword(\n                $user,\n                \'contrase\xc3\xb1a\'\n            ))\n
Run Code Online (Sandbox Code Playgroud)\n

在测试它是否有效时,我收到错误:

\n
\n

期望“Symfony\\Component\\Security\\Core\\User\\UserInterface”的实例作为第一个参数,但得到“App\\Entity\\Usuario”。

\n
\n

我不明白,因为它的字面意思是按照指南所示写的。
\n这些是我的文件:

\n

用户实体

\n
namespace App\\Entity;\n\nuse App\\Repository\\UsuarioRepository;\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Symfony\\Component\\Security\\Core\\User\\UserInterface;\n\n/**\n * @ORM\\Entity(repositoryClass=UsuarioRepository::class)\n */\nclass Usuario\n{\n    /**\n     * @ORM\\Id\n     * @ORM\\GeneratedValue\n     * @ORM\\Column(type="integer")\n     */\n    private $id;\n\n    /**\n     * @ORM\\Column(type="string", length=255)\n     */\n    private $nombre;\n\n    /**\n     * @ORM\\Column(type="string", length=255)\n     */\n    private $apellidos;\n\n    /**\n     * @ORM\\Column(type="string", length=180, unique=true)\n     */\n    private $email;\n\n    /**\n     * @ORM\\Column(type="json")\n     */\n    private $roles = [];\n\n    /**\n     * @var string The hashed password\n     * @ORM\\Column(type="string")\n     */\n    private $password;\n\n    /**\n     * @ORM\\Column(type="string", length=255)\n     */\n    private $prefijo;\n\n    /**\n    * @ORM\\Column(type="string", length=255)\n    */\n    private $telefono;\n\n    public function getId(): ?int\n    {\n        return $this->id;\n    }\n\n    public function getEmail(): ?string\n    {\n        return $this->email;\n    }\n\n    public function setEmail(string $email): self\n    {\n        $this->email = $email;\n\n        return $this;\n    }\n\n    /**\n     * A visual identifier that represents this user.\n     *\n     * @see UserInterface\n     */\n    public function getUsername(): string\n    {\n        return (string) $this->email;\n    }\n\n    /**\n     * @see UserInterface\n     */\n    public function getRoles(): array\n    {\n        $roles = $this->roles;\n        // guarantee every user at least has ROLE_USER\n        $roles[] = \'ROLE_USER\';\n\n        return array_unique($roles);\n    }\n\n    public function setRoles(array $roles): self\n    {\n        $this->roles = $roles;\n\n        return $this;\n    }\n\n    /**\n     * @see UserInterface\n     */\n    public function getPassword(): string\n    {\n        return $this->password;\n    }\n\n    public function setPassword(string $password): self\n    {\n        $this->password = $password;\n\n        return $this;\n    }\n\n    /**\n     * Returning a salt is only needed, if you are not using a modern\n     * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.\n     *\n     * @see UserInterface\n     */\n    public function getSalt(): ?string\n    {\n        return null;\n    }\n\n    /**\n     * @see UserInterface\n     */\n    public function eraseCredentials()\n    {\n        // If you store any temporary, sensitive data on the user, clear it here\n        // $this->plainPassword = null;\n    }\n\n    public function getNombre(): ?string\n    {\n        return $this->nombre;\n    }\n\n    public function setNombre(string $nombre): self\n    {\n        $this->nombre = $nombre;\n\n        return $this;\n    }\n\n    public function getApellidos(): ?string\n    {\n        return $this->apellidos;\n    }\n\n    public function setApellidos(string $apellidos): self\n    {\n        $this->apellidos = $apellidos;\n\n        return $this;\n    }\n\n    public function getPrefijo(): ?string\n    {\n        return $this->prefijo;\n    }\n\n    public function setPrefijo(string $prefijo): self\n    {\n        $this->prefijo = $prefijo;\n\n        return $this;\n    }\n\n    public function getTelefono(): ?string\n    {\n        return $this->telefono;\n    }\n\n    public function setTelefono(string $telefono): self\n    {\n        $this->telefono = $telefono;\n\n        return $this;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

控制器

\n
namespace App\\Controller;\n\nuse App\\Entity\\RegistroUsuario;\nuse App\\Form\\RegistroUsuarioForm;\nuse App\\Repository\\PrefijoTfnoPaisesRepository;\nuse App\\DataFixtures\\UsuarioFixtures;\nuse App\\Entity\\Usuario;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Routing\\Annotation\\Route;\nuse Symfony\\Component\\PasswordHasher\\Hasher\\UserPasswordHasherInterface;\n\n/**\n     * @Route("/usuario", name="usuario")\n     */\nclass UsuarioController extends AbstractController\n{\n    /**\n     * @Route("/", name="usuario")\n     */\n    public function index(Request $request, \n                        PrefijoTfnoPaisesRepository $prefijoTfnoPaisesRepository, \n                        UserPasswordHasherInterface $passwordHasher)\n    {\n    \n        $paramRegistroForm = new RegistroUsuario();\n        $registroFrom = $this->createForm(RegistroUsuarioForm::class, $paramRegistroForm);\n        $registroFrom->handleRequest($request);\n        $paisesPrefijo = $prefijoTfnoPaisesRepository->findAll();\n\n        if ($registroFrom->isSubmitted() && $registroFrom->isValid()){\n            $manager = $this->getDoctrine()->getManager();\n            // encode the plain password\n            \n            $user = new Usuario();\n            $user\n            ->setNombre("nombre")\n            ->setApellidos("apellidos")\n            ->setEmail("email@a.com")\n            ->setRoles(["rol"])\n            ->setPassword($passwordHasher->hashPassword(\n                $user,\n                \'contrase\xc3\xb1a\'\n            ))\n            ->setPrefijo("+34")\n            ->setTelefono("telefono")\n            ;\n            $manager->persist($user);\n            \n            $manager->flush();     \n    \n            dd($request->request->get(\'registro_usuario_form\'));\n        }       \n    \n        \n        return $this->render(\'usuario/index.html.twig\', [\n            \'registroFormulario\' => $registroFrom->createView(),\n            \'paisesPrefijo\' => $paisesPrefijo\n        ]);\n    }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n

安全.yaml

\n
security:\n    password_hashers:\n        App\\Entity\\Usuario:\n            # Use native password hasher, which auto-selects the best\n            # possible hashing algorithm (starting from Symfony 5.3 this is "bcrypt")\n            algorithm: auto\n\n
Run Code Online (Sandbox Code Playgroud)\n

yiv*_*ivi 11

您的Usuario实体应该实施UserInterface.

这是一个非常基本且简单的界面:

interface UserInterface
{
    public function getRoles();
    public function getPassword();
    public function getSalt();
    public function eraseCredentials();
    public function getUsername();
}
Run Code Online (Sandbox Code Playgroud)

您已经实现了必要的方法,但没有声明接口实现:

class Usuario implements UserInterface 
{ /* class implementation */ }
Run Code Online (Sandbox Code Playgroud)

为了向前兼容,您还应该实现getIdentifier()getUsername()将从 Symfony 6 上的接口中删除,并用此方法替换)。

简单地:

interface UserInterface
{
    public function getRoles();
    public function getPassword();
    public function getSalt();
    public function eraseCredentials();
    public function getUsername();
}
Run Code Online (Sandbox Code Playgroud)

此外,由于您的Usuario实体还实现getPassword()from UserInterface,因此您还应该实现PasswordAuthenticatedUserInterface. 这个新接口是在 5.3 中引入的,在 6.0getPassword()中将从中删除 UserInterface

class Usuario implements UserInterface 
{ /* class implementation */ }
Run Code Online (Sandbox Code Playgroud)

到 6.0 时,您可能也想摆脱它getSalt(),因为它将被从 中删除UserInterface(并移至LegacyPasswordAuthenticatedUserInterface()),但该方法不太可能在您的应用程序中有用(因为任何相对现代的哈希方法都会产生它自己的随机盐)。