php - Symfony 4 在登录失败时检索用户的电子邮件
问题描述
我创建了一个事件侦听器,以在用户登录尝试失败但无法获取与请求关联的用户名(在本例中为用户的电子邮件)时增加失败的登录计数。
class LoginFailureListener
{
private $requestStack;
private $entityManager;
public function __construct(RequestStack $requestStack, EntityManagerInterface $entityManager)
{
$this->requestStack = $requestStack;
$this->entityManager = $entityManager;
}
public function onAuthenticationFailure(AuthenticationFailureEvent $event)
{
$email = $event->getAuthenticationToken()->getUsername();
dump($email);
$email 的值是一个空字符串...我见过其他示例,其中 getUsername() 似乎返回了预期值。
在我的用户模型中,我定义了以下内容:
/**
* @see UserInterface
*/
public function getUsername(): string
{
return (string) $this->email;
}
安全.yaml:
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
main:
anonymous: true
guard:
authenticators:
- App\Security\LoginFormAuthenticator
form_login:
login_path: login
check_path: login
username_parameter: "email"
password_parameter: "password"
我是否需要在其他地方配置 getUsername 以便它返回用户的标识符(电子邮件)?
以下产生了所需的信息:
$email = $event->getAuthenticationToken()->getCredentials()['email'];
解决方案
没有其他地方必须配置 getUsername(),而是在您的实体中 - 这似乎没问题。
我的建议(以及 200 美元的赌注)是可能没有 authenticationToken,因为正是用户未能输入有效凭据。但是,即使是匿名用户也有会话令牌,所以你可以试试这个:
在侦听器的构造函数中注入 ContainerInterface $container,然后尝试
$token = $this->container->get('security.token_storage')->getToken();
$user = $token->getUser();
$email = $this->container->get('session')->get('_security.last_username');
dump($token, $user, $email);
如果没有电子邮件,则可能是因为在登录尝试后没有在会话中设置它。Symfony 通常在登录后立即执行此操作,使用任何扩展 AbstractFormLoginAuthenticator 的类,在方法 getCredentials()
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
请参阅https://symfony.com/doc/current/security/form_login_setup.html
希望这可以帮助你交配。祝你好运。
编辑:您的 security.yaml 似乎也不错,但请确保您已根据以下准则在下面定义您的表单登录:
form_login:
login_path: login # or whatever your path is
check_path: login # or whatever your path is
username_parameter: login[email] # these fields need to be as they appear in the html form
password_parameter: login[password]
default_target_path: index # or whatever your path is
provider: app_user_provider
推荐阅读
- unity3d - 我无法在 Unity U 建模器中围绕边缘挤出对象
- c# - 使用 System.Net.ICredentials 进行承载身份验证
- spring-boot - 如何使用 swagger 3 spring boot 记录 Spring Data 休息端点
- javascript - Why does Vue 3's `setup(props) { props.id }` return undefined
- r - 忽略 NA 的每个变量的 R-Count n
- html - 如何使宽度大于 100% 的 div 水平居中?
- c++ - 在 Windows 10 上使用 makefile 构建
- spring-boot - 多模块 Vaadin 项目生成文件到父模块
- list - Flutter - 从 2 个列表中获取搜索栏的建议并一起显示
- nextflow - splitCsv 为每一行多次加入通道 nextflow