Вход в Symfony 4.2 Метод checkCredentials возвращает false

При попытке войти в систему получаю информацию о том, что ввожу неверные данные. Метод возвращает false с сообщением:

Authentication failed because App\Security\LoginFormAuthenticator::checkCredentials() did not return true.

Логирование делаю на основе документации symfony https://symfony.com/doc/current/security/form_login_setup

Вход в Symfony 4.2 Метод checkCredentials возвращает false

Пользователь объекта

/**
 * @ORM\Entity(repositoryClass = "App\Repository\UserRepository")
 * @ORM\Table(name = "users")
 * @ORM\HasLifecycleCallbacks
 */
class User implements UserInterface
{
    /**
     * The unique auto incremented primary key.
     *
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer", unique=true)
     */
    private $id;

    /**
     * The internal primary identity key.
     *
     * @var int
     *
     * @ORM\Column(type = "integer", unique=true)
     */
    private $uid;

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

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

    /**
     * @var string The hashed password bcrypt
     * @ORM\Column(type = "string")
     */
    private $password;

    /**
     * @ORM\Column(type = "string", length = 50)
     *
     * @Assert\NotBlank(
     *      groups = {"Registration", "ChangeDetails"}
     * )
     *
     * @Assert\Length(
     *      min=3,
     *      max=50,
     *      groups = {"Registration", "ChangeDetails"}
     * )
     *
     * @var string
     */
    protected $name;

    /**
     * @ORM\Column(type = "string", length = 50)
     *
     * @Assert\NotBlank(
     *      groups = {"Registration", "ChangeDetails"}
     * )
     *
     * @Assert\Length(
     *      min=3,
     *      max=50,
     *      groups = {"Registration", "ChangeDetails"}
     * )
     *
     * @var string
     */
    protected $surname;

    /**
     * @ORM\Column(type = "string", length = 10000,)
     *
     *
     * @Assert\Length(
     *      max=10000,
     *      groups = {"Registration", "ChangeDetails"}
     * )
     *
     * @var string A detailed description of the user available to the application administrator
     */
    protected $description;

    /**
     * @ORM\Column(name = "account_locked", type = "boolean")
     *
     * @var bool
     */
    protected $accountLocked = false;

    /**
     * @ORM\Column(name = "register_date", type = "datetime")
     *
     * @var \DateTime
     */
    protected $createDate;

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

    public function getUid(): int
    {
        return $this->uid;
    }

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

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

        return $this;
    }

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUsername(): string
    {
        return (string) $this->email;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

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

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getPassword(): string
    {
        return (string) $this->password;
    }

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

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getSalt()
    {
        // not needed when using the "bcrypt" algorithm in security.yaml
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials()
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }

    public function __construct()
    {
        $this->registerDate = new \DateTime();
        $this->uid = mt_rand(100000, 999999);
    }

    /**
     * Get name.
     *
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Set surname.
     *
     * @param string $surname
     *
     * @return User
     */
    public function setSurname(string $surname): User
    {
        $this->surname = $surname;

        return $this;
    }

    /**
     * Get surname.
     *
     * @return string
     */
    public function getSurname(): string
    {
        return $this->surname;
    }

    /**
     * Set accountLocked.
     *
     * @param bool $accountLocked
     *
     * @return User
     */
    public function setAccountLocked(bool $accountLocked): User
    {
        $this->accountNonLocked = $accountLocked;

        return $this;
    }

    /**
     * Get accountLocked.
     *
     * @return bool
     */
    public function getAccountLocked(): bool
    {
        return $this->accountNonLocked;
    }

    public function serialize()
    {
        return serialize([
            $this->id,
            $this->username,
            $this->password,
        ]);
    }

    public function unserialize($serialized)
    {
        list(
            $this->id,
            $this->username,
            $this->password
            ) = unserialize($serialized);
    }

    /**
     * Set name.
     *
     * @param string $name
     *
     * @return User
     */
    public function setName(string $name): User
    {
        $this->name = $name;

        return $this;
    }
}  

Контроллер безопасности

class SecurityController extends AbstractController
    {
        /**
         * @Route("/login", name = "login")
         */
        public function login(AuthenticationUtils $authenticationUtils): Response
        {
            $error = $authenticationUtils->getLastAuthenticationError();
            $lastUsername = $authenticationUtils->getLastUsername();

            return $this->render('security/login.html.twig', [
                'last_username' => $lastUsername,
                'error' => $error,
                ]);
        }
    }

Security/Loginformauthenticator

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    private $entityManager;
    private $router;
    private $csrfTokenManager;
    private $passwordEncoder;

    public function __construct(EntityManagerInterface $entityManager, RouterInterface $router, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->entityManager = $entityManager;
        $this->router = $router;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
    }

    public function supports(Request $request)
    {
        return 'login' === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'email' => $request->request->get('email'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];
        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['email']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);

        if (!$user) {
            throw new CustomUserMessageAuthenticationException('Email could not be found.');
        }

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        $param = $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
        return $param;
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->router->generate('panel_dashboard'));
    }

    protected function getLoginUrl()
    {
        return $this->router->generate('login');
    }
}

security.uaml

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt


    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            guard:
                authenticators:
                    - App\Security\LoginFormAuthenticator

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    access_control:
         - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/panel, roles: ROLE_ADMIN }
         - { path: ^/profile, roles: ROLE_USER }

Форма входа

   <form method = "post" class = "form-horizontal form-material" id = "loginform">
        {% if error %}
        <div class = "alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
        {% endif %}
        <h3 class = "text-center m-b-20">{% trans %}Sign In{% endtrans %}</h3>
        <div class = "form-group ">
            <div class = "col-xs-12">
                <input type = "email" value = "{{ last_username }}" name = "email" class = "form-control" placeholder = "{% trans %}Username{% endtrans %}" required> 
            </div>
        </div>
        <div class = "form-group">
            <div class = "col-xs-12">
                <input  name = "password" type = "password" class = "form-control" placeholder = "{% trans %}Password{% endtrans %}" required>
            </div>
        </div>
        <input type = "hidden" name = "_csrf_token" value = "{{ csrf_token('authenticate') }}">    
        <div class = "form-group row">
            <div class = "col-md-12">
                <div class = "d-flex no-block align-items-center">
                    <div class = "custom-control custom-checkbox">
                        <input name = "_remember_me" type = "checkbox" class = "custom-control-input" id = "customCheck1">
                        <label class = "custom-control-label" for = "customCheck1">{% trans %}Remember me{% endtrans %}</label>
                    </div> 
                    <div class = "ml-auto">
                        <a href = "javascript:void(0)" id = "to-recover" class = "text-muted"><i class = "fas fa-lock m-r-5"></i>{% trans %} Forgot pwd{% endtrans %}?</a>
                    </div>
                </div>
            </div>
        </div>
        <div class = "form-group text-center">
            <div class = "col-xs-12 p-b-20">
                <button class = "btn btn-block btn-lg btn-info btn-rounded" type = "submit">{% trans %}Log In{% endtrans %}</button>
            </div>
        </div>
    </form>

Пользовательские приспособления

class UserFixtures extends Fixture
{
    /**
     * @var UserPasswordEncoderInterface
     */
    private $passwordEncoder;

    /**
     * UserFixtures constructor.
     *
     * @param UserPasswordEncoderInterface $passwordEncoder
     */
    public function __construct(UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->passwordEncoder = $passwordEncoder;
    }

    /**
     * @return int
     */
    public function getOrder()
    {
        return 0;
    }

    /**
     * @param ObjectManager $manager
     *
     * @throws \Exception
     */
    public function load(ObjectManager $manager)
    {
        $usersList = [
            [
                'name' => 'Tomasz',
                'surname' => 'Kowalik',
                'description' => 'Vestibulum non ipsum. Curabitur egestas. Integer hendrerit purus consectetuer adipiscing elit. In sodales in, elementum vel, velit. Suspendisse fermen',
                'email' => '[email protected]',
                'password' => 'password',
                'role' => 'ROLE_ADMIN',
                'points' => '0',
            ],

        ];

        foreach ($usersList as $userDetails) {
            $user = new User();
            $user->setName($userDetails['name'])
                    ->setSurname($userDetails['surname'])
                    ->setPassword($this->passwordEncoder->encodePassword($user, $userDetails['surname']))
                    ->setDescription($userDetails['description'])
                    ->setEmail($userDetails['email'])
                    ->setPoints($userDetails['points'])
                    ->setRoles([$userDetails['role']])
                    ->setCreateDate(new \DateTime());

            $this->addReference('user-'.$userDetails['surname'], $user);

            $manager->persist($user);
        }

        $manager->flush();
    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
2 333
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я проверял сохраненный в базе хэш вручную и после кодировки пароля пароль не давал хеш от базы. Причина в ошибке:

setPassword ($ this-> passwordEncoder-> encodePassword ($ user, $ userDetails ['surname'])) // surname -> password

Я была такая же проблема. При переключении со старого на новый метод кодирования длина моего пароля была слишком большой, чтобы поместиться в БД, поэтому хешированный пароль был усечен.

Vulkhan 18.12.2021 08:24

Другие вопросы по теме