Symfony 4登录表单服务器身份验证失败,无法正常工作

问题描述 投票:0回答:1

我的symfony 4登录表单有问题。我正在按照文档进行操作:https://symfony.com/doc/current/security/form_login_setup.html

可以正常工作,然后密码和电子邮件正确,但是如果在数据库中找不到电子邮件和/或密码,则不会发生任何事情

我的MainFormAuthentication:

<?php

namespace App\Security;

use App\Entity\Users;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;

class MainFormAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    private $entityManager;
    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;

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

    public function supports(Request $request)
    {
        return 'app_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(Users::class)->findOneBy(['email' => $credentials['email']]);

        if (!$user) {
            // fail authentication with a custom error
            throw new CustomUserMessageAuthenticationException('Email could not be found.');
        }

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

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }
        return new RedirectResponse($this->urlGenerator->generate('dashboard'));
    }
//    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
//    {
//        return $this->urlGenerator->generate('app_login');
//    }

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate('app_login');
    }
}

我的MainSecurityController:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class MainSecurityController extends AbstractController
{
    /**
     * @Route("/login", name="app_login")
     */
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        // if ($this->getUser()) {
        //     return $this->redirectToRoute('target_path');
        // }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

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

    /**
     * @Route("/logout", name="app_logout")
     */
    public function logout()
    {
        throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
    }
}

我的登录树枝:

{% extends 'main/main_layout.html.twig' %}

{% block title %}Log in!{% endblock %}

{% block leftcontent %}
    {{ dump(error) }}
<form method="post">
    {% if error %}
        <div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
    {% endif %}

    {% if app.user %}
        <div class="mb-3">
            You are logged in as {{ app.user.username }}, <a href="{{ path('app_logout') }}">Logout</a>
        </div>
    {% endif %}

    <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
    <label for="inputEmail">Email</label>
    <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" required autofocus>
    <label for="inputPassword">Password</label>
    <input type="password" name="password" id="inputPassword" class="form-control" required>

    <input type="hidden" name="_csrf_token"
           value="{{ csrf_token('authenticate') }}"
    >

    {#
        Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
        See https://symfony.com/doc/current/security/remember_me.html

        <div class="checkbox mb-3">
            <label>
                <input type="checkbox" name="_remember_me"> Remember me
            </label>
        </div>
    #}

    <button class="btn btn-lg btn-primary" type="submit">
        Sign in
    </button>
</form>
{% endblock %}

我的security.yaml:

security:
    encoders:
        App\Entity\Users:
            algorithm: auto
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\Users
                property: email
        # used to reload user from session & other features (e.g. switch_user)
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
#            anonymous: ~
            guard:
                authenticators:
#                    - App\Security\LoginFormAuthenticator
                    - App\Security\MainFormAuthenticator
                entry_point: App\Security\MainFormAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                target: app_login

            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/dashboard/admin/, roles: ROLE_ADMIN }
        - { path: ^/dashboard/manager/, roles: ROLE_MANAGER }
        - { path: ^/dashboard/arendator/, roles: ROLE_ARENDATOR }
        - { path: ^/dashboard/user/, roles: ROLE_USER }
        # may be yes, may be no...
        - { path: ^/api$, roles: IS_AUTHENTICATED_ANONYMOUSLY }

第一次编辑

在[[security.yaml中进行了更改,但仍然无法使用:

security: encoders: App\Entity\Users: algorithm: auto # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers providers: # used to reload user from session & other features (e.g. switch_user) app_user_provider: entity: class: App\Entity\Users property: email # used to reload user from session & other features (e.g. switch_user) firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true # anonymous: ~ guard: # delete entry_point, and left only one authenticator in guard: authenticators: - App\Security\MainFormAuthenticator logout: path: app_logout # where to redirect after logout target: app_login # activate different ways to authenticate # https://symfony.com/doc/current/security.html#firewalls-authentication # https://symfony.com/doc/current/security/impersonating_user.html # switch_user: true # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/dashboard/admin/, roles: ROLE_ADMIN } - { path: ^/dashboard/manager/, roles: ROLE_MANAGER } - { path: ^/dashboard/arendator/, roles: ROLE_ARENDATOR } - { path: ^/dashboard/user/, roles: ROLE_USER } # may be yes, may be no... - { path: ^/api$, roles: IS_AUTHENTICATED_ANONYMOUSLY }

这是日志中发生的,然后身份验证失败:

[2020-01-19 17:11:57] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\MainSecurityController::login"},"request_uri":"http://127.0.0.1:8000/login","method":"POST"} [] [2020-01-19 17:11:57] php.INFO: User Deprecated: Creating Doctrine\ORM\Mapping\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Creating Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. at C:\\Users\\andre\\Desktop\\Git_Projects\\openserver\\OSPanel\\domains\\parkingapp\\vendor\\doctrine\\orm\\lib\\Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy.php:66)"} [] [2020-01-19 17:11:57] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} [] [2020-01-19 17:11:57] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:11:57] security.DEBUG: Calling getCredentials() on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:11:57] security.DEBUG: Passing guard token information to the GuardAuthenticationProvider {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:11:58] doctrine.DEBUG: SELECT t0.id AS id_1, t0.email AS email_2, t0.roles AS roles_3, t0.password AS password_4, t0.user_login AS user_login_5, t0.user_block_state AS user_block_state_6, t0.user_date_create AS user_date_create_7 FROM users t0 WHERE t0.email = ? LIMIT 1 ["[email protected]"] [] [2020-01-19 17:12:00] security.INFO: Guard authentication failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): Authentication failed because App\\Security\\MainFormAuthenticator::checkCredentials() did not return true. at C:\\Users\\andre\\Desktop\\Git_Projects\\openserver\\OSPanel\\domains\\parkingapp\\vendor\\symfony\\security-guard\\Provider\\GuardAuthenticationProvider.php:113)","authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:12:00] security.DEBUG: The "App\Security\MainFormAuthenticator" authenticator set the response. Any later authenticator will not be called {"authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:12:02] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\MainSecurityController::login"},"request_uri":"http://127.0.0.1:8000/login","method":"GET"} [] [2020-01-19 17:12:02] php.INFO: User Deprecated: Creating Doctrine\ORM\Mapping\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Creating Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. at C:\\Users\\andre\\Desktop\\Git_Projects\\openserver\\OSPanel\\domains\\parkingapp\\vendor\\doctrine\\orm\\lib\\Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy.php:66)"} [] [2020-01-19 17:12:02] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} [] [2020-01-19 17:12:02] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:12:02] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} [] [2020-01-19 17:12:02] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
我的用户实体类:

<?php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Entity(repositoryClass="App\Repository\UsersRepository") */ class Users implements UserInterface { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=180, unique=true) */ private $email; /** * @ORM\Column(type="json") */ private $roles = []; /** * @var string The hashed password * @ORM\Column(type="string") */ private $password; /** * @ORM\Column(type="string", length=100) */ private $userLogin; /** * @ORM\Column(type="boolean") */ private $userBlockState; /** * @ORM\Column(type="datetime") */ private $userDateCreate; /** * @ORM\OneToMany(targetEntity="App\Entity\UserCards", mappedBy="this_user") */ private $userCards; /** * @ORM\OneToMany(targetEntity="App\Entity\Transactions", mappedBy="this_user") */ private $transactions; /** * @ORM\ManyToMany(targetEntity="App\Entity\Parkings", inversedBy="linkedusers") */ private $linkedparkings; // /** // * @ORM\ManyToMany(targetEntity="App\Entity\Parkings", inversedBy="linkeduser") // */ // private $linkedparkings; // // /** // * @ORM\ManyToMany(targetEntity="App\Entity\Parkings", mappedBy="has_user") // */ // private $has_parking; public function __construct() { $this->userCards = new ArrayCollection(); $this->transactions = new ArrayCollection(); // $this->linkedparkings = new ArrayCollection(); // $this->has_parking = new ArrayCollection(); } public function getId(): ?int { return $this->id; } 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 getUserLogin(): ?string { return $this->userLogin; } public function setUserLogin(string $userLogin): self { $this->userLogin = $userLogin; return $this; } public function getUserBlockState(): ?bool { return $this->userBlockState; } public function setUserBlockState(bool $userBlockState): self { $this->userBlockState = $userBlockState; return $this; } public function getUserDateCreate(): ?\DateTimeInterface { return $this->userDateCreate; } public function setUserDateCreate(\DateTimeInterface $userDateCreate): self { $this->userDateCreate = $userDateCreate; return $this; } /** * @return Collection|UserCards[] */ public function getUserCards(): Collection { return $this->userCards; } public function addUserCard(UserCards $userCard): self { if (!$this->userCards->contains($userCard)) { $this->userCards[] = $userCard; $userCard->setThisUser($this); } return $this; } public function removeUserCard(UserCards $userCard): self { if ($this->userCards->contains($userCard)) { $this->userCards->removeElement($userCard); // set the owning side to null (unless already changed) if ($userCard->getThisUser() === $this) { $userCard->setThisUser(null); } } return $this; } /** * @return Collection|Transactions[] */ public function getTransactions(): Collection { return $this->transactions; } public function addTransaction(Transactions $transaction): self { if (!$this->transactions->contains($transaction)) { $this->transactions[] = $transaction; $transaction->setThisUser($this); } return $this; } public function removeTransaction(Transactions $transaction): self { if ($this->transactions->contains($transaction)) { $this->transactions->removeElement($transaction); // set the owning side to null (unless already changed) if ($transaction->getThisUser() === $this) { $transaction->setThisUser(null); } } return $this; } /** * @return Collection|Parkings[] */ public function getLinkedparkings(): Collection { return $this->linkedparkings; } public function addLinkedparking(Parkings $linkedparking): self { if (!$this->linkedparkings->contains($linkedparking)) { $this->linkedparkings[] = $linkedparking; } return $this; } public function removeLinkedparking(Parkings $linkedparking): self { if ($this->linkedparkings->contains($linkedparking)) { $this->linkedparkings->removeElement($linkedparking); } return $this; } // /** // * @return Collection|Parkings[] // */ // public function getLinkedparkings(): Collection // { // return $this->linkedparkings; // } // // public function addLinkedparking(Parkings $linkedparking): self // { // if (!$this->linkedparkings->contains($linkedparking)) { // $this->linkedparkings[] = $linkedparking; // } // // return $this; // } // // public function removeLinkedparking(Parkings $linkedparking): self // { // if ($this->linkedparkings->contains($linkedparking)) { // $this->linkedparkings->removeElement($linkedparking); // } // // return $this; // } // // /** // * @return Collection|Parkings[] // */ // public function getHasParking(): Collection // { // return $this->has_parking; // } // // public function addHasParking(Parkings $hasParking): self // { // if (!$this->has_parking->contains($hasParking)) { // $this->has_parking[] = $hasParking; // $hasParking->addHasUser($this); // } // // return $this; // } // // public function removeHasParking(Parkings $hasParking): self // { // if ($this->has_parking->contains($hasParking)) { // $this->has_parking->removeElement($hasParking); // $hasParking->removeHasUser($this); // } // // return $this; // } }

也许有人已经遇到问题了?
php symfony
1个回答
1
投票
更改security.yaml中的防护并删除entry_point: App\Security\MainFormAuthenticator

guard: authenticators: - App\Security\MainFormAuthenticator

编辑:

编辑您的身份验证器并添加此内容:

... use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; class MainFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface{ ...

© www.soinside.com 2019 - 2024. All rights reserved.