使用自定义用户提供程序时无法提交表单

时间:2019-08-26 17:00:30

标签: php symfony4

我正在建立一个登录系统,女巫依靠对另一个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');
    }
}

0 个答案:

没有答案