首页 > 解决方案 > 如何在我的 LoginController 中捕获由 UserProvider::refreshUser() 引发的异常消息?

问题描述

我有一个使用稍微修改过的应用程序AbstractFormLoginAuthenticator来提供身份验证,所以我有自定义\App\Security\UserProvider\App\Security\Authenticator类。这些目前都运行良好,我现在想添加一个新功能。在该UserProvider::refreshUser()方法中,我想添加一个可能立即使会话无效的检查。例如,也许用户记录有一个布尔active字段,如果在用户会话期间该字段已切换为 false,我想立即将用户注销。我有这样的事情:

public function refreshUser(UserInterface $user)
{
    if ($someCondition) {
        throw new UsernameNotFoundException('You have been logged out for reasons.');
    }
    return $user;
}

这可以按预期工作——当用户发出新请求时,条件触发,身份验证被清除,用户立即被重定向到登录控制器。但是,我有一个挥之不去的问题。我想向用户展示发生了什么。即,用户应该看到“您因某种原因已退出登录”。

但是,抛出的异常不能像抛出的异常那样通过AuthenticationUtils::getLastAuthenticationError()方法获得\App\Security\Authenticator。因此,我似乎无法在控制器中获取该消息文本并将其传递给视图。

我试过 throwing CustomUserMessageAuthenticationException,它也没有传播。我检查了会话数据,并验证那里没有存储对异常的引用。我是否需要自己手动将其添加到会话中,然后将其拉回控制器中?或者 Symfony 是否有一些我缺少的内置机制?

TL;DR如果我在 Authenticator 中抛出异常,我可以通过调用从后续登录控制器中获取它getLastAuthenticationError()。如何对我的 UserProvider 中抛出的异常执行相同操作?

[更新]我能够通过使用 a 来完成我想要的,然后使用查找CustomUserMessageAuthenticationException的密钥将其手动插入到会话中:getLastAuthenticationError()

public function refreshUser(UserInterface $user)
{
    if ($someCondition) {
        $e = new CustomUserMessageAuthenticationException('You have been logged out for reasons.');
        $this->session->set(Security::AUTHENTICATION_ERROR, $e);
        throw $e;
    }
    return $user;
}

我不确定这是否理想,如果有人有替代品,我很乐意接受。

标签: phpsymfonyauthenticationsymfony4

解决方案


推荐阅读