Php can';使用自定义用户提供程序时不提交表单
我正在设置一个登录系统,它依赖于对另一个web服务的curl调用来通过登录表单对用户进行身份验证,为此,我按照文档使用maker bundle生成一个自定义用户提供者、一个用户模型、一个SecurityController和一个LoginFormAthenticator。 表单将显示,但不提交,并且不会给出任何错误,以帮助我进行调试 根据symfony文档,LoginFormAthenticator的支持方法每次都会在控制器之前调用,事实上,当我在其中写入骰子时,它会显示我在骰子中放入的内容 除此之外,我还尝试在登录操作中手动创建表单,并检查是否提交,但表单没有提交。 3天以来我一直在努力解决这个问题 登录表单Php can';使用自定义用户提供程序时不提交表单,php,symfony4,Php,Symfony4,我正在设置一个登录系统,它依赖于对另一个web服务的curl调用来通过登录表单对用户进行身份验证,为此,我按照文档使用maker bundle生成一个自定义用户提供者、一个用户模型、一个SecurityController和一个LoginFormAthenticator。 表单将显示,但不提交,并且不会给出任何错误,以帮助我进行调试 根据symfony文档,LoginFormAthenticator的支持方法每次都会在控制器之前调用,事实上,当我在其中写入骰子时,它会显示我在骰子中放入的内容 除
{% extends 'base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
{{ encore_entry_link_tags('login') }}
{% endblock %}
{% block body %}
<form class="form-signin" method="post" action="{{ path('app_login') }}">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<h1 class="h3 mb-3 font-weight-normal">Connectez vous</h1>
<label for="inputEmail" class="sr-only">Email</label>
<input type="email" value="" name="email" id="inputEmail" class="form-control" placeholder="Email" required autofocus>
<label for="inputPassword" class="sr-only">Mot de passe</label>
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Mot de passe" required>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
<button class="btn btn-lg btn-primary" type="submit">
Connexion
</button>
</form>
{% endblock %}
SecurityController.php
class SecurityController extends AbstractController
{
/**
* @param AuthenticationUtils $authenticationUtils
* @return Response
* @Route("/login", name="app_login")
*/
public function login(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', [
'last_username' => $lastUsername,
'error' => $error
]);
}
}
用户模型(因为我没有使用条令)
用户提供者
class UserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// Load a User object from your data source or throw UsernameNotFoundException.
// The $username argument may not actually be a username:
// it is whatever value is being returned by the getUsername()
// method in your User class.
throw new \Exception('TODO: fill in loadUserByUsername() inside
'.__FILE__);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Invalid user class
"%s".', get_class($user)));
}
// Return a User object after making sure its data is "fresh".
// Or throw a UsernameNotFoundException if the user no longer exists.
throw new \Exception('TODO: fill in refreshUser() inside '.__FILE__);
}
public function supportsClass($class)
{
return User::class === $class;
}
}
LoginFormAthenticator这个类应该处理登录系统的每个操作
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $urlGenerator;
private $csrfTokenManager;
public function __construct(UrlGeneratorInterface $urlGenerator,
CsrfTokenManagerInterface $csrfTokenManager)
{
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
}
public function supports(Request $request)
{
return 'app_login' === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
return $credentials;
}
public function getUser($credentials, UserProviderInterface
$userProvider)
{
$token = new CsrfToken('authenticate',
$credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
// Load / create our user however you need.
// You can do this by calling the user provider, or with custom logic here.
$user = $userProvider->loadUserByUsername($credentials['email']);
if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Email could not be found.');
}
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
// Check the user's password or other credentials and return true or false
// If there are no credentials to check, you can just return true
throw new \Exception('TODO: check the credentials inside '.__FILE__);
}
public function onAuthenticationSuccess(Request $request,
TokenInterface $token, $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(),
$providerKey)) {
return new RedirectResponse($targetPath);
}
// For example : return new RedirectResponse($this->urlGenerator-
>generate('some_route'));
throw new \Exception('TODO: provide a valid redirect inside
'.__FILE__);
}
protected function getLoginUrl()
{
return $this->urlGenerator->generate('app_login');
}
}
我解决了它,因为我使用的是网页加密,有一个js文件,我阻止表单提交。我解决了它,因为我使用的是网页加密,有一个js文件,我阻止表单提交。
class UserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// Load a User object from your data source or throw UsernameNotFoundException.
// The $username argument may not actually be a username:
// it is whatever value is being returned by the getUsername()
// method in your User class.
throw new \Exception('TODO: fill in loadUserByUsername() inside
'.__FILE__);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Invalid user class
"%s".', get_class($user)));
}
// Return a User object after making sure its data is "fresh".
// Or throw a UsernameNotFoundException if the user no longer exists.
throw new \Exception('TODO: fill in refreshUser() inside '.__FILE__);
}
public function supportsClass($class)
{
return User::class === $class;
}
}
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $urlGenerator;
private $csrfTokenManager;
public function __construct(UrlGeneratorInterface $urlGenerator,
CsrfTokenManagerInterface $csrfTokenManager)
{
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
}
public function supports(Request $request)
{
return 'app_login' === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
return $credentials;
}
public function getUser($credentials, UserProviderInterface
$userProvider)
{
$token = new CsrfToken('authenticate',
$credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
// Load / create our user however you need.
// You can do this by calling the user provider, or with custom logic here.
$user = $userProvider->loadUserByUsername($credentials['email']);
if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Email could not be found.');
}
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
// Check the user's password or other credentials and return true or false
// If there are no credentials to check, you can just return true
throw new \Exception('TODO: check the credentials inside '.__FILE__);
}
public function onAuthenticationSuccess(Request $request,
TokenInterface $token, $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(),
$providerKey)) {
return new RedirectResponse($targetPath);
}
// For example : return new RedirectResponse($this->urlGenerator-
>generate('some_route'));
throw new \Exception('TODO: provide a valid redirect inside
'.__FILE__);
}
protected function getLoginUrl()
{
return $this->urlGenerator->generate('app_login');
}
}