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



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

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

我的主窗体身份验证:

<?php
namespace AppSecurity;
use AppEntityUsers;
use DoctrineORMEntityManagerInterface;
use SymfonyComponentHttpFoundationRedirectResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentRoutingGeneratorUrlGeneratorInterface;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityCoreEncoderUserPasswordEncoderInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityCoreExceptionCustomUserMessageAuthenticationException;
use SymfonyComponentSecurityCoreExceptionInvalidCsrfTokenException;
use SymfonyComponentSecurityCoreSecurity;
use SymfonyComponentSecurityCoreUserUserInterface;
use SymfonyComponentSecurityCoreUserUserProviderInterface;
use SymfonyComponentSecurityCsrfCsrfToken;
use SymfonyComponentSecurityCsrfCsrfTokenManagerInterface;
use SymfonyComponentSecurityGuardAuthenticatorAbstractFormLoginAuthenticator;
use SymfonyComponentSecurityHttpUtilTargetPathTrait;
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');
}
}

我的主安全控制器:

<?php
namespace AppController;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;
use SymfonyComponentSecurityHttpAuthenticationAuthenticationUtils;
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 %}

我的安全.yaml:

security:
encoders:
AppEntityUsers:
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: AppEntityUsers
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:
#                    - AppSecurityLoginFormAuthenticator
- AppSecurityMainFormAuthenticator
entry_point: AppSecurityMainFormAuthenticator
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:
AppEntityUsers:
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: AppEntityUsers
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:
- AppSecurityMainFormAuthenticator
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 DoctrineORMMappingUnderscoreNamingStrategy 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 ["adminmail123@gmail.com"] []
[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 "AppSecurityMainFormAuthenticator" 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 DoctrineORMMappingUnderscoreNamingStrategy 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 AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentSecurityCoreUserUserInterface;
/**
* @ORMEntity(repositoryClass="AppRepositoryUsersRepository")
*/
class Users implements UserInterface
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=180, unique=true)
*/
private $email;
/**
* @ORMColumn(type="json")
*/
private $roles = [];
/**
* @var string The hashed password
* @ORMColumn(type="string")
*/
private $password;
/**
* @ORMColumn(type="string", length=100)
*/
private $userLogin;
/**
* @ORMColumn(type="boolean")
*/
private $userBlockState;
/**
* @ORMColumn(type="datetime")
*/
private $userDateCreate;
/**
* @ORMOneToMany(targetEntity="AppEntityUserCards", mappedBy="this_user")
*/
private $userCards;
/**
* @ORMOneToMany(targetEntity="AppEntityTransactions", mappedBy="this_user")
*/
private $transactions;
/**
* @ORMManyToMany(targetEntity="AppEntityParkings", inversedBy="linkedusers")
*/
private $linkedparkings;
//    /**
//     * @ORMManyToMany(targetEntity="AppEntityParkings", inversedBy="linkeduser")
//     */
//    private $linkedparkings;
//
//    /**
//     * @ORMManyToMany(targetEntity="AppEntityParkings", 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;
//    }
}

也许有人已经遇到了问题?

在 security.yaml 中更改守卫并删除entry_point: AppSecurityMainFormAuthenticator

guard:
authenticators:
- AppSecurityMainFormAuthenticator

编辑:

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

...
use SymfonyComponentSecurityGuardPasswordAuthenticatedInterface;
class MainFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface{
...

最新更新