我正在建立一个登录系统,女巫依靠对另一个Web服务的curl调用来通过登录表单对用户进行身份验证,为此,我通过使用maker捆绑包生成了一个自定义用户提供程序来遵循文档。用户模型,一个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 %}
Security.yaml
security:
providers:
app_user_provider:
id: App\Security\UserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
logout: ~
guard:
authenticators:
- App\Security\LoginFormAuthenticator
access_control:
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
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
]);
}
}
用户模型(因为我没有使用Doctrine)
class User implements UserInterface
{
private $email;
private $roles = [];
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string
{
return (string) $this->email;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* @see UserInterface
*/
public function getPassword()
{
// not needed for apps that do not check user passwords
}
/**
* @see UserInterface
*/
public function getSalt()
{
// not needed for apps that do not check user passwords
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
}
UserProvider
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');
}
}