You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 4自定义用户提供者从数据库取用户返回“Bad Credentials”

解决Symfony 4自定义用户提供者的"Bad Credentials"问题

看起来你的问题核心出在Doctrine DQL查询的实体引用错误,导致无法从数据库获取用户数据,最终触发UsernameNotFoundException,进而返回"Bad credentials"错误。咱们一步步来排查修复:

1. 修正DQL查询的实体类引用

你当前的查询用了数据库表名users,但Doctrine的DQL要求使用实体类的完全限定类名(FQCN),而非数据库表名。比如如果你的用户实体是App\Entity\User,查询需要改成:

$userData = $this->doctrine->getManager()
    ->createQueryBuilder('SELECT u FROM App\Entity\User u WHERE u.email = :email')
    ->setParameter('email', $email)
    ->getQuery()
    ->getOneOrNullResult();

小提示:可以查看你的用户实体类上的@ORM\Table注解确认映射关系,比如实体类里如果有@ORM\Table(name="users"),说明这个实体对应数据库的users表,但DQL查询必须用实体类名,不能直接用表名。

2. 修复UsernameNotFoundException的变量未定义问题

当$userData不存在时,你抛出异常用了$username变量,但这个变量只有在$userData存在时才会赋值,会导致未定义变量错误。应该直接用传入的$email:

throw new UsernameNotFoundException(
    sprintf('Username "%s" does not exist.', $email)
);

3. 调试查询结果的小技巧

如果修正查询后还是没返回数据,可以打印生成的SQL语句来排查问题:

$query = $this->doctrine->getManager()
    ->createQueryBuilder('SELECT u FROM App\Entity\User u WHERE u.email = :email')
    ->setParameter('email', $email)
    ->getQuery();

// 打印生成的SQL,方便验证是否正确
var_dump($query->getSQL());
$userData = $query->getOneOrNullResult();
var_dump($userData);
exit;

这样能直观看到SQL是否符合预期,参数是否正确绑定。

4. 检查WebserviceUser类的实现

确保你的WebserviceUser类正确实现了Symfony\Component\Security\Core\User\UserInterface,特别是getUsername()、getPassword()、getRoles()这些核心方法,它们是Security组件验证身份的关键。

一个基础的WebserviceUser实现示例:

<?php
// src/Security/User/WebserviceUser.php
namespace App\Security\User;

use Symfony\Component\Security\Core\User\UserInterface;

class WebserviceUser implements UserInterface
{
    private $email;
    private $password;
    private $salt;
    private $roles;

    public function __construct(string $email, string $password, ?string $salt, array $roles)
    {
        $this->email = $email;
        $this->password = $password;
        $this->salt = $salt;
        $this->roles = $roles;
    }

    public function getUsername(): string
    {
        // 如果用邮箱作为用户名,直接返回email即可
        return $this->email;
    }

    public function getPassword(): string
    {
        return $this->password;
    }

    public function getSalt(): ?string
    {
        return $this->salt;
    }

    public function getRoles(): array
    {
        return $this->roles;
    }

    public function eraseCredentials()
    {
        // 可选:清空敏感临时数据
    }
}

总结

最关键的问题是DQL查询误用了数据库表名而非实体类名,导致无法获取用户数据。修正这个问题后,再检查异常变量、实体类实现这些细节,应该就能解决"Bad credentials"的错误了。

内容的提问来源于stack exchange,提问作者user3684098

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:59:59