无效的凭据消息登录 Symfony 4.4

Posted

技术标签:

【中文标题】无效的凭据消息登录 Symfony 4.4【英文标题】:Invalid credentials message login Symfony 4.4 【发布时间】:2021-05-20 16:26:34 【问题描述】:

我正在尝试在 Symfony 4.4 中登录一个用户,但我收到此消息“无效凭据”。我不知道如何解决它。我在这个平台上看到了一些帖子,我没有解决我的问题。

security.yalm 文件

security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
    users:
        entity:
            # the class of the entity that represents users
            class: 'App\Entity\User'
            property: 'email'
encoders:
    # use your user class name here
    App\Entity\User:
        # Use native password encoder
        # This value auto-selects the best possible hashing algorithm
        # (i.e. Sodium when available).
        algorithm: bcrypt    
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    main:
        anonymous: lazy
        provider: users
        guard:
            authenticators:
                - App\Security\LoginFormAuthenticator
        logout:
            path: logout
            # where to redirect after logout
            # target: app_any_route

        # 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: ^/admin, roles: ROLE_ADMIN 
    # -  path: ^/profile, roles: ROLE_USER 

LoginFormAuthenticator.php

类 LoginFormAuthenticator 扩展 AbstractFormLoginAuthenticator 使用 TargetPathTrait;

public const LOGIN_ROUTE = 'login';

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

public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager)

    $this->entityManager = $entityManager;
    $this->urlGenerator = $urlGenerator;
    $this->csrfTokenManager = $csrfTokenManager;


public function supports(Request $request)

    return self::LOGIN_ROUTE === $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) 
        // fail authentication with a custom error
        throw new CustomUserMessageAuthenticationException('Email could not be found.');
    

    return $user;


public function checkCredentials($credentials, UserInterface $user)

    return "Logeado";
    // Check the user's password or other credentials and return true or false
    // If there are no credentials to check, you can just return true
    throw new \Exception('TODO: check the credentials inside '.__FILE__);


public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)

    if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) 
        return new RedirectResponse($targetPath);
    

    // For example : return new RedirectResponse($this->urlGenerator->generate('some_route'));
    throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);


protected function getLoginUrl()

    return $this->urlGenerator->generate(self::LOGIN_ROUTE);

用户实体

class User implements UserInterface

/**
 * @ORM\Id
 * @ORM\GeneratedValue
 * @ORM\Column(type="integer")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255)
 */
private $username;

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

/**
 * @ORM\Column(type="string", length=255)
 */
private $email;

/**
 * @ORM\Column(type="boolean")
 */
private $isVerified = false;

public function getId(): ?int

    return $this->id;


public function getUsername(): ?string 

    return $this->username;


public function setUsername(string $username): self

    $this->username = $username;

    return $this;


public function getPassword(): ?string

    return $this->password;


public function setPassword(string $password): self

    $this->password = $password;

    return $this;


public function getEmail(): ?string

    return $this->email;


public function setEmail(string $email): self

    $this->email = $email;

    return $this;


public function getRoles()

    // TODO: Implement getRoles() method.


public function getSalt()

    // TODO: Implement getSalt() method.


public function eraseCredentials()

    // TODO: Implement eraseCredentials() method.


public function isVerified(): bool

    return $this->isVerified;


public function setIsVerified(bool $isVerified): self

    $this->isVerified = $isVerified;

    return $this;

SecurityController.php

class SecurityController extends AbstractController

/**
 * @Route("/login", name="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="logout")
 */
public function logout()

    throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');

【问题讨论】:

关于这个确切的主题有很多问题。你说你看了一些,但他们没有解决问题。对我们帮助不大。您的“匿名:懒惰”确实很奇怪。由于您只是在学习,我建议您创建一个新的 4.4 项目,然后完全按照安全文档进行操作,直到您得到一些有用的东西。之后,您可能会拥有解决特定问题所需的东西。 我做到了。我使用了官方文档,并使用了它所说的命令来创建新项目。这是此命令创建的默认设置。我只更改此文件中的提供程序配置 您的 security.yaml 文件是否有编码器部分?我觉得无聊,做了一个新的 4.4 项目,运行 make:user 和 make:auth,一切都开箱即用。 默认情况下它没有,但我更新了 de post,现在它有一个编码器部分。但是,无效的凭据消息仍然存在。您可以将您的项目更新到 github 以寻找两者之间的差异吗? 您发布的 Authenticator::checkCredientals 方法有 'return "Logeado";'我认为那只是为了调试?让它返回 true,看看这是否会让你有不同的体验。 【参考方案1】:

如果您将属性设置为“电子邮件” 在您的用户实体中,getusername 必须返回您应该更改的电子邮件

【讨论】:

为什么?因为我有两种方法(getUsername 和 get Email) 是的,身份验证将始终调用 getusername 并且应该返回电子邮件而不是用户名 如何更新它?因为我更改了它并清除了缓存但它不起作用 我需要你检查一下我的 security.yaml 我定义了 anonymous:true 和 lazy:true 但你把它设置为 anonymous: lazy 这可能是个问题 在 security.yaml 中将 user provider 属性设置为 email 将导致使用 getEmail。所以你几乎可以忽略这个答案,因为它完全是错误的。

以上是关于无效的凭据消息登录 Symfony 4.4的主要内容,如果未能解决你的问题,请参考以下文章

直接访问登录表单时未设置会话 cookie,导致 CSRF 令牌无效

Symfony 5 / 使用 API 编写自定义身份验证总是返回我无效的凭据

令牌在尝试刷新后被取消身份验证

Symfony 4.4 安全性在登录后获取具有关系实体数据的用户

FCM 推送 - 请求具有无效的身份验证凭据。预期的 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据

Symfony2 安全,使用 sha512,不工作。收到错误凭据消息