Symfony 3 - обрабатывать процесс входа вручную - PullRequest
2 голосов
/ 07 ноября 2019

Я пытаюсь обработать весь процесс входа в систему вручную с помощью службы, определенной ниже

<?php

namespace StandardBundle\Security;

use \PDO;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;

class AuthenticateUser
{
    private $sesion;
    private $security;
    private $em;
    private $factory;

    public function __construct(SessionInterface $session, TokenStorageInterface $security, EntityManagerInterface $em, EncoderFactoryInterface $factory)
    {
        $this->session = $session;
        $this->security   = $security;
        $this->em      = $em;
        $this->factory = $factory;
    }

    public function identification($login, $passw)
    {
        if( ('' === $login || null === $login) || ('' === $passw || null === $passw) ) {
            throw new \InvalidArgumentException('Login and password can\'t be empty');
        }

        // getRepo
        $repo = $this->em->getRepository("StandardBundle:User");

        // getUser
        $user = $repo->findOneBy(array('username' => $login));

        // check user exists
        if(!$user){
            return false;
        }

        // get encoder
        $encoder = $this->factory->getEncoder($user);

        // get salt
        $salt = $user->getSalt();

        // Check password is valid
        if(!$encoder->isPasswordValid($user->getPassword(), $passw, $salt)) {
            throw new BadCredentialsException('Bad credentials');
        }

        // generate token
        $token = new UsernamePasswordToken($user, $user->getPassword(), 'main', array('ROLE_VISITEUR'));
        // set token
        $this->security->setToken($token);

        // If the firewall name is not main, then the set value would be instead:
        // $this->get('session')->set('_token_XXXFIREWALLNAMEXXX', serialize($token));
        $this->session->set('_token_main', serialize($token));
        // save
        $this->session->save();
    }
}

А вот loginAction в контроллере

<?php

public function loginAction(Request $request)
  {
    if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
      return $this->redirectToRoute('home');
    }

    if ($request->isMethod('POST')){
        $authenticateUser = $this->get("standard.authenticate_user");
        $authenticateUser->identification('fakeuser','myfakepassw');
    }

    $authenticationUtils = $this->get('security.authentication_utils');

    // get the login error if there is one
    $error = $authenticationUtils->getLastAuthenticationError();

    $lastUsername = $authenticationUtils->getLastUsername();

    $defaultData = array(
      //'action' => $this->generateUrl('login_check')
      'action' => $this->generateUrl('login_' . $request->getLocale())
    );

    $form = $this->createForm(LoginForm::class, array(), $defaultData);
    $form->get('_username')->setData($lastUsername);
    $form->get('_failure_path')->setData($request->getPathInfo());

    $form->handleRequest($request);

    if (!is_null($error)) {
      $form->addError(
        new FormError($error->getMessage())
      );      
    }

    return $this->render('@Standard/login.html.twig', array(
      'form' => $form->createView()
    ));
  }

И мой login.twig.html

{{ form_start(form) }}

    {% form_theme form _self %}

    {% block form_errors %}
      {% if errors is defined and errors|length > 0 %}
        <div class="alert alert-danger">
          {% for error in errors %}
            <div>{{ error.message|trans }}</div>
          {% endfor %}
        </div>
      {% endif %}      
    {% endblock %}

    {{ form_errors(form) }}    

    <div class="form-group">
      {# Génération du label. #}
      {{ form_label(form.login, "LibLogin") }}
      {{ form_widget(form.login, {'attr': {'class': 'form-control'}}) }}
    </div>
    <div class="form-group">
      {# Génération du label. #}
      {{ form_label(form.passw, "LibPassw") }}
      {{ form_widget(form.passw, {'attr': {'class': 'form-control'}}) }}      
    </div>
      {{ form_widget(form.submit, {'label':'LibConnexion','attr': {'class': 'btn btn-primary'}}) }}

    {{ form_end(form) }}

Кажется, это работает хорошо, но когда предоставляется неверная информация, мой сервис выдает BadCredentialsException, который не перехватывается Symfony и не может быть получен с помощью

$authenticationUtils = $this->get('security.authentication_utils');

// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();

Ожидаемый enter image description here Получил enter image description here

Как настроить Symfony для отображения моего исключения в форме ошибки?

1 Ответ

0 голосов
/ 08 ноября 2019

Вы отображали ошибки формы в вашем шаблоне? {{ form_errors(form) }} Как this ...

Или вы можете выполнить проверку учетных данных для формы с помощью FormEvents, например this . Затем обработайте форму, например this , что означает, что форма действительна, если учетные данные действительны (затем войдите в систему и перенаправьте пользователя) или в противном случае отобразите ошибки формы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...