视图错误:SymfonyComponentSecurityCoreExceptionBadCredentialsException:呈现的密码不能为空.
in log:security。验证器不支持请求。{"firewall_name"main"authenticator":"App 安全 AppCustomAuthenticator"} []
:安全。验证器不支持请求。{"firewall_name"main"authenticator":"Symfony Http 身份 安全 组件FormLoginAuthenticator"} []
在security.yaml:
security:
# https://symfony.com/doc/current/security/experimental_authenticators.html
enable_authenticator_manager: true
# https://symfony.com/doc/current/security.html#c-hashing-passwords
password_hashers:
AppEntityUser:
algorithm: auto
SymfonyComponentSecurityCoreUserPasswordAuthenticatedUserInterface:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: AppEntityUser
property: email
# used to reload user from session & other features (e.g. switch_user)
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
#provider: users_in_memory
custom_authenticators:
- AppSecurityAppCustomAuthenticator
form_login:
# "login" is the name of the route created previously
login_path: login
check_path: login
failure_path: login
enable_csrf: true
username_parameter: _email
password_parameter: _password
target_path_parameter: go_to
logout:
path: logout
# where to redirect after logout
target: Accueil
invalidate_session: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
##ad a remember me option aut login
remember_me:
secret: '%kernel.secret%'
# ...
always_remember_me: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
在控制器:
namespace AppController;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;
use SymfonyComponentSecurityHttpAuthenticationAuthenticationUtils;
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="login", methods={"GET","POST"})]
*
*/
public function index(AuthenticationUtils $authenticationUtils): Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', [
'controller_name' => 'LoginController',
'last_email' => $lastUsername,
'error' => $error,
]);
}
/**
* @Route("/logout", name="logout", methods={"GET"})
*/
public function logout(): void//?Response
{
}
}
in UserRepository:
namespace AppRepository;
use AppEntityUser;
use DoctrineBundleDoctrineBundleRepositoryServiceEntityRepository;
use DoctrinePersistenceManagerRegistry;
use SymfonyComponentSecurityCoreExceptionUnsupportedUserException;
use SymfonyComponentSecurityCoreUserPasswordAuthenticatedUserInterface;
use SymfonyComponentSecurityCoreUserPasswordUpgraderInterface;
/**
* @method User|null find($id, $lockMode = null, $lockVersion = null)
* @method User|null findOneBy(array $criteria, array $orderBy = null)
* @method User[] findAll()
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, User::class);
}
/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}
$user->setPassword($newHashedPassword);
$this->_em->persist($user);
$this->_em->flush();
}
// /**
// * @return User[] Returns an array of User objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->orderBy('u.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/
public function findOneBySomeField($value): ?User
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
}
枝:{%扩展'base.html。嫩枝' %}{
% use "base.html.twig" with stylesheets as style_parent %}
{% block stylesheets %}
{{ block('style_parent') }}
<link rel="stylesheet" href="{{ asset('css/login-form.css') }}">
{% endblock %}
{% block title %}Se logger pour obtenir toutes les fonctionnalités{% endblock %}
{% block body %}
{% use "background_menu.html.twig" with header as parent_menu %}
{% block header %}
{{ block('parent_menu') }}
{% endblock %}
{% if error %}
<div class="alert alert-danger text-align-center">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{% if app.user %}
<div class="form-group text-align-center">
{{ app.user.email }}, Vous êtes Connecté, <a href="{{ path('logout') }}" class="a-passw-regist">Déconnexion</a>
</div>
{% endif %}
<form action="{{ path('login') }}" method="post">
<h1 class="h1-register-form text-align-center margin-bottom-50px">Connectez-vous</h1>
<div class="d-flex justify-content-center display-flex-column">
<div class="form-group">
<label for="email">Email:</label>
<input class="form-control" type="text" id="email" name="_email" value="{% if last_email %}{{ last_email }}{% endif %}"/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input class="form-control" type="password" id="_password" name="password"/>
</div>
{% if error %}
<div class="color:red">{{ error }}</div>
{% endif %}
{# If you want to control the URL the user is redirected to on success #}
<input type="hidden" name="_target_path" value="{{ path('Accueil') }}"/>
<div class="form-group">
<a href="{{ path('register')}}" class="a-passw-regist">S'inscrire</a> ou <a href="#" class="a-passw-regist">Mot de Passe oublié</a>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<input type="hidden" name="go_to" value="{{ path('Accueil') }}"/>
<button type="submit" name="login">Connection</button>
</div>
</form>
<br><br><br><br>
{% use "footer.html.twig" with footer as parent_footer %}
{% block footer %}
{{ block('parent_footer') }}
{% endblock %}
{% endblock %}
在AppCustomAuthenticator:
//src/安全/AppCustomAuthenticator.php
namespace AppSecurity;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface;
use SymfonyComponentSecurityCoreExceptionAuthenticationException;
use SymfonyComponentSecurityCoreExceptionCustomUserMessageAuthenticationException;
use SymfonyComponentSecurityHttpAuthenticatorAbstractAuthenticator;
use SymfonyComponentSecurityHttpAuthenticatorPassportBadgeUserBadge;
use SymfonyComponentSecurityHttpAuthenticatorPassportPassportInterface;
use SymfonyComponentSecurityHttpAuthenticatorPassportSelfValidatingPassport;
use SymfonyComponentHttpFoundationRedirectResponse;
use SymfonyComponentRoutingGeneratorUrlGeneratorInterface;
class AppCustomAuthenticator extends AbstractAuthenticator
{
private $router;
public function __construct(UrlGeneratorInterface $router)
{
$this->router = $router;
}
/**
* Called on every request to decide if this authenticator should be
* used for the request. Returning `false` will cause this authenticator
* to be skipped.
*/
public function supports(Request $request): ?bool
{
return $request->headers->has('X-AUTH-TOKEN');
}
public function authenticate(Request $request): PassportInterface
{
$apiToken = $request->headers->get('X-AUTH-TOKEN');
if (null === $apiToken) {
// The token header was empty, authentication fails with HTTP Status
// Code 401 "Unauthorized"
throw new CustomUserMessageAuthenticationException('No API token provided');
}
return new SelfValidatingPassport(new UserBadge($apiToken));
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
// on success, let the request continue
//return null;
return new RedirectResponse($this->router->generate('Accueil'));
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
$data = [
// you may want to customize or obfuscate the message first
'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
// or to translate this message
// $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
];
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
}
现在是你的答案了:
<input class="form-control" type="password" id="_password" name="_password"/>
<input class="form-control" type="text" id="_email" name="_email" value="{% if last_email %}{{ last_email }}{% endif %}"/>
替换后:
<input type="hidden" name="go_to" value="{{path('Accueil') }}"/>
由:
<input type="hidden" name="go_to" value="Accueil"/>
和security.yaml:
form_login:
# "login" is the name of the route created previously
login_path: login
check_path: login
failure_path: login
enable_csrf: true
username_parameter: _email
password_parameter: _password
target_path_parameter: go_to