Метод onAuthenticationFailure
Метод onAuthenticationFailure принадлежит абстрактному классу AbstractAuthenticator и вызывается автоматически, когда процесс аутентификации завершился неудачно. Первым параметром передаётся объект Request - текущий HTTP-запрос. Вторым параметром передаётся объект AuthenticationException - исключение, описывающее причину сбоя. Метод обязан вернуть объект Response, который Symfony отправит клиенту. По умолчанию в AbstractAuthenticator этот метод объявлен абстрактным, поэтому его необходимо реализовать в собственном аутентификаторе.
Синтаксис
abstract public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
Пример
Давайте создадим аутентификатор, который при неудачной попытке входа возвращает JSON-ответ с сообщением об ошибке:
<?php
namespace AppSecurity;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityHttpAuthenticatorAbstractAuthenticator;
use SymfonyComponentSecurityHttpAuthenticatorPassportBadgeUserBadge;
use SymfonyComponentSecurityHttpAuthenticatorPassportPassport;
class ApiAuthenticator extends AbstractAuthenticator
{
public function supports(Request $request): ?bool
{
return $request->headers->has('X-AUTH-TOKEN');
}
public function authenticate(Request $request): Passport
{
$token = $request->headers->get('X-AUTH-TOKEN');
if ($token !== 'abcde') {
throw new AuthenticationException('Invalid token');
}
return new Passport(
new UserBadge('user'),
[]
);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
return new Response(
json_encode(['error' => $exception->getMessageKey()]),
Response::HTTP_UNAUTHORIZED
);
}
public function onAuthenticationSuccess(Request $request, $passport, string $firewallName): ?Response
{
return null;
}
}
?>
Результат выполнения кода при неверном токене:
{"error":"Invalid token"}
Пример
Давайте при неудачной аутентификации перенаправим пользователя на страницу входа с сохранением сообщения об ошибке:
<?php
namespace AppSecurity;
use SymfonyComponentHttpFoundationRedirectResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingGeneratorUrlGeneratorInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityHttpAuthenticatorAbstractAuthenticator;
use SymfonyComponentSecurityHttpAuthenticatorPassportBadgeUserBadge;
use SymfonyComponentSecurityHttpAuthenticatorPassportPassport;
class FormAuthenticator extends AbstractAuthenticator
{
public function __construct(
private UrlGeneratorInterface $urlGenerator
) {
}
public function supports(Request $request): ?bool
{
return $request->isMethod('POST') && $request->attributes->get('_route') === 'app_login';
}
public function authenticate(Request $request): Passport
{
$username = $request->request->get('username');
$password = $request->request->get('password');
if ($username !== 'user' || $password !== 'hello') {
throw new AuthenticationException('Invalid credentials');
}
return new Passport(
new UserBadge($username),
[]
);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
$request->getSession()->set('auth_error', $exception->getMessageKey());
return new RedirectResponse(
$this->urlGenerator->generate('app_login')
);
}
public function onAuthenticationSuccess(Request $request, $passport, string $firewallName): ?Response
{
return new RedirectResponse(
$this->urlGenerator->generate('app_home')
);
}
}
?>
Результат выполнения кода - перенаправление на маршрут 'app_login' с кодом ответа 302.
Смотрите также
-
класс
AbstractAuthenticator,
который является базой для собственных аутентификаторов -
метод
authenticate,
который выполняет проверку учётных данных -
метод
onAuthenticationSuccess,
который обрабатывает успешную аутентификацию -
класс
Passport,
который хранит данные аутентификации