Symfony 4,登录,如何调试错误“无效凭据”?
Posted
技术标签:
【中文标题】Symfony 4,登录,如何调试错误“无效凭据”?【英文标题】:Symfony 4, Login, how debug the error 'Invalid credentials'? 【发布时间】:2018-06-11 12:42:43 【问题描述】:从 symfony 4 开始,我想创建一个简单的身份验证表单。我创建了一个用户类(标识符是电子邮件字段,而不是“用户名”,我创建了一个类控制器并配置了 security.yml 文件。
我用这个静态方法创建了一些用户:(对于测试,默认密码是'test')
class User implements \Serializable, UserInterface
// ...
public static function new_alea($email, $isActive = false, $password="test")
$instance = new self();
$instance->isActive = $isActive;
$instance->email = $email;
$brypt = new BCryptPasswordEncoder(4);
$instance->password = $brypt->encodePassword($password, null);
return $instance;
// ...
它的工作,我的数据库中有一些用户使用加密密码。
但是当我进入表单页面并尝试登录(填写电子邮件/密码字段并单击提交按钮)时,我收到错误“凭据无效”。
这个错误意味着什么?如何/在哪里调试我的代码以查找为什么会发生此错误?
下面,我的代码的主要部分,也许你会看到一个我没有看到的错误:
security.yaml 文件:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
my_db_provider:
entity:
class: App\Entity\User
property: email
firewalls:
main:
provider: my_db_provider
anonymous: ~
form_login:
login_path: login
check_path: login
role_hierarchy:
# ...
用户实体类:
class User implements \Serializable, UserInterface
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\Column(type="string", length=255, unique=true)
*/
private $email;
/**
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
private $plainPassword;
public static function new_alea($email, $isActive = false, $password="coucou")
$instance = new self();
$instance->isActive = $isActive;
$instance->email = $email;
$brypt = new BCryptPasswordEncoder(4);
$instance->password = $brypt->encodePassword($password, null);
return $instance;
public function eraseCredentials()
$this->plainPassword = null;
public function serialize()
return serialize(array(
$this->id,
$this->email,
$this->password,
));
public function unserialize($serialized)
list (
$this->id,
$this->email,
$this->password,
) = unserialize($serialized);
public function getRoles()
return array('ROLE_ADMIN');
public function getPassword()
return $this->password;
public function setPassword($password)
$this->password = $password;
public function getUsername()
return $this->email;
public function setUsername($email)
$this->email = $email;
public function getPlainPassword()
return $this->plainPassword;
public function setPlainPassword($plainPassword): void
$this->plainPassword = $plainPassword;
// and others getters/setters
登录控制器:
class LoginController extends Controller
/**
* @Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $authUtils)
// get the login error if there is one
$error = $authUtils->getLastAuthenticationError();
// last username entered by the user
$email = $authUtils->getLastUsername();
return $this->render('frontend/log/login.html.twig', array(
'email' => $email,
'error' => $error,
));
还有模板 login.html.twig 文件:
% extends 'base.html.twig' %
% block body %
% if error %
<div> error.messageKey|trans(error.messageData, 'security') </div>
% endif %
<form action=" path('login') " method="post">
<label for="email">Email:</label>
<input type="text" id="email" name="_email" value=" email " />
<label for="password">Password:</label>
<input type="password" id="password" name="_password" />
#
If you want to control the URL the user
is redirected to on success (more details below)
<input type="hidden" name="_target_path" value="/account" />
#
<button type="submit">login</button>
</form>
% endblock body %
【问题讨论】:
在 User 的 ... 部分中,您是否实现了所有 UserInterface 方法?特别是getUsername()? 是的,你可以在我的粘贴中看到 getUsername() :) 嗯。在安全性下:添加“hide_user_not_found: false”这会将消息更改为“找不到用户”或“无效密码”。这将验证问题出在密码上并缩小范围。 顺便说一下,如果您查看Security Config Docs,您会看到 bcrypt 编码器的默认成本为 13。这也可能是问题所在。 bcrypt encoder details 啊哈!在您的表单中,name="_email" 应该是 name="_username" 或者在 form_login 下被覆盖。 【参考方案1】:嗨,我今天遇到了同样的问题,对我来说,这是我在字符串密码中限制了字符数。所以密码错误,因为编码占用了太多字符。所以我删除了字符的限制并且它起作用了。
【讨论】:
【参考方案2】:只需在“frontend”错误消息下方输出 error
即可获取完整的堆栈跟踪等...
【讨论】:
【参考方案3】:在您的登录模板中,添加 dump(error)
。它包括真正的错误消息(通常就足够了),以及整个堆栈跟踪(如果需要)。而且格式比 error
更好:
% if error %
dump(error)
<div> error.messageKey|trans(error.messageData, 'security') </div>
% endif %
【讨论】:
【参考方案4】:我遇到了类似的问题,我通过将密码从纯文本更改为编码版本来解决。
# I create users by fixtures
$user->setEmail('admin@admin');
$user->setPassword('admin'); // Wrong
$user->setPassword($this->passwordEncoder->encodePassword(
$user,
'admin'
)); // Correct
官方参考:https://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html#accessing-services-from-the-fixtures
【讨论】:
【参考方案5】:使用两个具有相同功能名称和不同标签名称的路由器路径,以便在用户名和密码正确时移动到您的登录路径。当您的密码或用户名无效时,它将移动到另一个路径。
示例:
index:
path: /
controller: App\Controller\DefaultController::login
login:
path: /login
controller: App\Controller\DefaultController::login
【讨论】:
以上是关于Symfony 4,登录,如何调试错误“无效凭据”?的主要内容,如果未能解决你的问题,请参考以下文章
spring security reactive - 如何调试“无效凭据”错误?
如何在 Symfony 4 中创建登录页面而不会出现“InvalidConfigurationException”错误?