如何在 Symfony 5.4 中创建不同的身份验证错误消息?
How to create different the authentication error message in Symfony 5.4?
默认情况下,它显示错误“无效凭据”。我已经看到类似“转到翻译,创建 security.en.yaml 并键入以下内容的答案:
# translations/security.en.yaml
'Invalid credentials.': 'Invalid email or password'
但是如何创建不同的错误呢?例如,密码错误时显示“密码无效”,电子邮件错误时显示“电子邮件不存在”。怎么做?
您必须创建自定义授权和例外。
示例:
config/packages/security.yaml
security:
enable_authenticator_manager: true
...
providers:
...
firewalls:
...
client:
pattern: ^/
custom_authenticators:
- App\Security\ClientLoginFormAuthenticator
logout:
path: store.account.logout
target: store.home
access_control:
...
src/Security/ClientLoginFormAuthenticator.php
<?php
declare(strict_types=1);
namespace App\Security;
use App\Repository\UserRepository;
use App\Security\Exception\CustomException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use function in_array;
class ClientLoginFormAuthenticator extends AbstractLoginFormAuthenticator
{
private const LOGIN_ROUTE = 'store.account.login';
public function __construct(private UserRepository $userRepository, private UrlGeneratorInterface $urlGenerator)
{}
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function authenticate(Request $request): Passport
{
$password = $request->request->get('_password');
$username = $request->request->get('_username');
$csrfToken = $request->request->get('_csrf_token');
return new Passport(
new UserBadge($username, function ($userIdentifier) {
$user = $this->userRepository->findOneBy(['email' => $userIdentifier]);
if ($user && in_array('ROLE_CLIENT', $user->getRoles(), true)) {
return $user;
}
//next condition
if($user && $user->getEmail() === 'superadmin@example.com') {
throw new CustomException();
}
throw new BadCredentialsException(); //default exception
}),
new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
src/Security/Exception/CustomException.php
<?php
namespace App\Security\Exception;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class CustomException extends AuthenticationException
{
/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return 'My Message.';
}
}
对我有用! :) 祝你好运!
默认情况下,它显示错误“无效凭据”。我已经看到类似“转到翻译,创建 security.en.yaml 并键入以下内容的答案:
# translations/security.en.yaml
'Invalid credentials.': 'Invalid email or password'
但是如何创建不同的错误呢?例如,密码错误时显示“密码无效”,电子邮件错误时显示“电子邮件不存在”。怎么做?
您必须创建自定义授权和例外。
示例: config/packages/security.yaml
security:
enable_authenticator_manager: true
...
providers:
...
firewalls:
...
client:
pattern: ^/
custom_authenticators:
- App\Security\ClientLoginFormAuthenticator
logout:
path: store.account.logout
target: store.home
access_control:
...
src/Security/ClientLoginFormAuthenticator.php
<?php
declare(strict_types=1);
namespace App\Security;
use App\Repository\UserRepository;
use App\Security\Exception\CustomException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use function in_array;
class ClientLoginFormAuthenticator extends AbstractLoginFormAuthenticator
{
private const LOGIN_ROUTE = 'store.account.login';
public function __construct(private UserRepository $userRepository, private UrlGeneratorInterface $urlGenerator)
{}
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function authenticate(Request $request): Passport
{
$password = $request->request->get('_password');
$username = $request->request->get('_username');
$csrfToken = $request->request->get('_csrf_token');
return new Passport(
new UserBadge($username, function ($userIdentifier) {
$user = $this->userRepository->findOneBy(['email' => $userIdentifier]);
if ($user && in_array('ROLE_CLIENT', $user->getRoles(), true)) {
return $user;
}
//next condition
if($user && $user->getEmail() === 'superadmin@example.com') {
throw new CustomException();
}
throw new BadCredentialsException(); //default exception
}),
new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
src/Security/Exception/CustomException.php
<?php
namespace App\Security\Exception;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class CustomException extends AuthenticationException
{
/**
* {@inheritdoc}
*/
public function getMessageKey()
{
return 'My Message.';
}
}
对我有用! :) 祝你好运!