drctyr2869
2019-02-28 19:19
浏览 59
已采纳

登录Symfony 4.2方法checkCredentials返回false

When I try to log into the system I get information that I enter incorrect data. The method returns false with the message:

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

Logging I do based on the symfony documentation https://symfony.com/doc/current/security/form_login_setup

enter image description here

Entity User

/**
 * @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;
    }
}  

SecurityConroller

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 login

   <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>

UserFixtures

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' => 'tomek@test.pl',
                '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();
    }
}
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • doulun1666 2019-03-05 14:32
    已采纳

    I checked the hash saved in the database manually and after encoding the password, the password did not give a hash from the database. The reason is the error:

    setPassword ($ this-> passwordEncoder-> encodePassword ($ user, $ userDetails ['surname'])) // surname -> password
    
    已采纳该答案
    打赏 评论

相关推荐 更多相似问题