Symfony中认证失败(账户未激活)时如何在登录页显示错误信息?
实现步骤
1. 自定义Authenticator处理认证失败异常
在你的自定义Authenticator类(比如App\Security\LoginFormAuthenticator)中,重写onAuthenticationFailure方法,专门捕获CustomUserMessageAccountStatusException,将错误信息存入会话后重定向回登录页:
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; use Symfony\Component\Security\Core\Security; class LoginFormAuthenticator extends AbstractLoginFormAuthenticator { // ... 其他已实现的方法 public function onAuthenticationFailure(Request $request, AuthenticationException $exception): Response { // 捕获账户未激活的异常 if ($exception instanceof CustomUserMessageAccountStatusException) { $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); } else { // 处理其他认证失败场景 parent::onAuthenticationFailure($request, $exception); } return $this->redirectToRoute('app_login'); } }
2. 在SecurityController传递错误信息到模板
确保SecurityController的login方法通过AuthenticationUtils获取错误信息,传递给Twig模板:
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; class SecurityController extends AbstractController { #[Route('/login', name: 'app_login')] public function login(AuthenticationUtils $authenticationUtils): Response { // 获取最后一次认证错误 $error = $authenticationUtils->getLastAuthenticationError(); // 获取上次输入的用户名 $lastUsername = $authenticationUtils->getLastUsername(); return $this->render('security/login.html.twig', [ 'last_username' => $lastUsername, 'error' => $error, ]); } }
3. 在Twig登录模板显示错误信息
在你的登录模板(templates/security/login.html.twig)中,添加错误提示的渲染逻辑:
{% if error %} <div class="alert alert-danger"> {{ error.message }} </div> {% endif %} <form method="post"> <div> <label for="username">用户名:</label> <input type="text" id="username" name="_username" value="{{ last_username }}"> </div> <div> <label for="password">密码:</label> <input type="password" id="password" name="_password"> </div> <button type="submit">登录</button> </form>
关键说明
CustomUserMessageAccountStatusException抛出的自定义消息'Your user account is not activated'可以直接通过error.message获取,无需额外翻译处理(如果需要国际化,可改用error.messageKey|trans(error.messageData, 'security'))。- 确认你的自定义Authenticator已在
config/packages/security.yaml中配置为当前防火墙的认证器,替代默认表单认证逻辑。
内容的提问来源于stack exchange,提问作者Eferra83
相关产品推荐
相关产品推荐

