Symfony 4 $encoder->encodePassword($user, $password) 上出现错误;

标签 symfony

我被 Sf4 困住了:

我想在没有FOS的情况下制作Auth系统,但是当我想制作我的reset-pwd功能时,我遇到了这个错误:

Argument 1 passed to UserPasswordEncoder::encodePassword() must implement interface UserInterface, array given, called in SecurityController.php on line 56

我的SecurityController.php:

<?php

namespace App\Controller;

use App\Form\ChangePasswordType;
use App\Entity\User;

use App\Repository\UserRepository;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends AbstractController {
    public function login(AuthenticationUtils $helper): Response {
        return $this->render('security/login.html.twig', [
            // dernier username saisi (si il y en a un)
            'last_username' => $helper->getLastUsername(),
            // La derniere erreur de connexion (si il y en a une)
            'error' => $helper->getLastAuthenticationError(),
        ]);
    }

    public function logout(): void {
        throw new \Exception('This should never be reached!');
    }


    public function resetpwd (Request $request, UserPasswordEncoderInterface $encoder) {

        $manager = $this->getDoctrine()->getManager();

        $changePassword = $request->request->get('change_password');

        $username = $changePassword['username'];
        $password = $changePassword['password']['first'];

        $user = new User();

        $user = $manager->getRepository(User::class)->findBy(['username' => $username]);

        if (!$username) {
            $this->addFlash('danger', 'User not found for '. $username);
        }

        $form = $this->createForm(ChangePasswordType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            try {
                $pass = $encoder->encodePassword($user, $password);
                $user->setPassword($pass);
                $manager->flush();
                $this->addFlash('success', 'Password Changed!');
            } catch (Exception $e) {
                $this->addFlash('danger', 'Something went skew-if. Please try again.');
            }
            return $this->redirectToRoute('athena_restepwd');
        }
        return $this->render('security/reset.html.twig', array('form' => $form->createView()));
    }
}

我的用户实体:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @ORM\Table(name="user")
 * @UniqueEntity(fields="email", message="Email déjà pris")
 * @UniqueEntity(fields="username", message="Username déjà pris")
 */
class User implements UserInterface, \Serializable {
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string")
     * @Assert\NotBlank()
     */
    private $fullName;

    /**
     * @var string
     *
     * @ORM\Column(type="string", unique=true)
     * @Assert\NotBlank()
     */
    private $username;

    /**
     * @var string
     *
     * @ORM\Column(type="string", unique=true)
     * @Assert\NotBlank()
     * @Assert\Email()
     */
    private $email;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=64)
     */
    private $password;

    /**
     * @var array
     *
     * @ORM\Column(type="array")
     */
    private $roles = [];

    public function getId(): int {
        return $this->id;
    }

    public function setFullName(string $fullName): void {
        $this->fullName = $fullName;
    }

    public function getFullName(): ?string {
        return $this->fullName;
    }

    public function getUsername(): ?string {
        return $this->username;
    }

    public function setUsername(string $username): void {
        $this->username = $username;
    }

    public function getEmail(): ?string {
        return $this->email;
    }

    public function setEmail(string $email): void {
        $this->email = $email;
    }

    public function getPassword(): ?string {
        return $this->password;
    }

    public function setPassword(string $password): void {
        $this->password = $password;
    }

    /**
     * Retourne les rôles de l'user
     */
    public function getRoles(): array {
        $roles = $this->roles;

        // Afin d'être sûr qu'un user a toujours au moins 1 rôle
        if (empty($roles)) {
            $roles[] = 'ROLE_USER';
        }

        return array_unique($roles);
    }

    public function setRoles(array $roles): void {
        $this->roles = $roles;
    }

    /**
     * Retour le salt qui a servi à coder le mot de passe
     *
     * {@inheritdoc}
     */
    public function getSalt(): ?string {
        // See "Do you need to use a Salt?" at https://symfony.com/doc/current/cookbook/security/entity_provider.html
        // we're using bcrypt in security.yml to encode the password, so
        // the salt value is built-in and you don't have to generate one

        return null;
    }

    /**
     * Removes sensitive data from the user.
     *
     * {@inheritdoc}
     */
    public function eraseCredentials(): void {
        // Nous n'avons pas besoin de cette methode car nous n'utilions pas de plainPassword
        // Mais elle est obligatoire car comprise dans l'interface UserInterface
        // $this->plainPassword = null;
    }

    /**
     * {@inheritdoc}
     */
    public function serialize(): string {
        return serialize([$this->id, $this->username, $this->password]);
    }

    /**
     * {@inheritdoc}
     */
    public function unserialize($serialized): void {
        [$this->id, $this->username, $this->password] = unserialize($serialized, ['allowed_classes' => false]);
    }
}

我也尝试使用 $user2 = new User(); 创建第二个假用户,并在 $pass = $encoder->encodePassword($user, $password) 上使用它;错误消息更改为:调用数组上的成员函数setPassword(),所以我认为我的实体是错误的,但我发现了我的错误

尊敬,

最佳答案

您将一个数组分配给 $user 变量:

    $user = new User();

    $user = $manager->getRepository(User::class)->findBy(['username' => $username]);

    if (!$username) {
        $this->addFlash('danger', 'User not found for '. $username);

Repository 的类方法 findBy 返回一个实体数组。请改用 findOneBy

关于Symfony 4 $encoder->encodePassword($user, $password) 上出现错误;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52384233/

相关文章:

php - 如何在 Symfony 2 中有效地使用 paginate with doctrine?

symfony - 如何访问 Symfony2 中的嵌套参数值?

php - 从继承的 Controller 调用表单

javascript - 无法在 Dropzone 中上传超过 1mb 的文件

Symfony\Component\Locale\Stub\StubIntlDateFormatter::__construct() 方法的参数 $locale 值 'en_IN' 行为未实现

symfony - 如何使用symfony2中的表单获取输入类型是数字?

login - Symfony3 - 扩展命名空间

symfony - google calendar api 错误 400 - 资源 ID 值无效

php - Symfony 2.8 和 PHP 7.4 : Warning: "continue" targeting switch is equivalent to "break". Composer 是最新版本

symfony - Symfony2,以微秒为单位的学说日期时间