Asynchroniczne logowanie - kpiorun/symfony2 GitHub Wiki

Założenia:

  1. Rozwiązanie musi używać obecny w Symfony2 komponent Security.
  2. Rozwiązanie musi logować użytkownika dokładnie z użyciem tego samego url-a, standardowo jest to /login_check, ale w przypadku gdy jest to zapytanie ajax-owe powinno zwrócić w odpowiedzi poprawną odpowiedź w formacie JSON.
  3. Odpowiedź powinna być równa: { result: true; } gdy użytkownik podał poprawne dane, lub { result: false; } w przeciwnym przypadku.

W celu wykorzystania komponentu Security zmienione zostały ustawienia form_login w pliku app/config/Security Należy przechwycić zdarzenie success lub failure rezygnując z defaultowej ścieżki.

 `# app/config/security.yml
    security:
        encoders:
            FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
         ROLE_ADMIN:       ROLE_USER
         ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
         fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                #csrf_provider: form.csrf_provider
                #default_target_path: /generuj-kod
                use_referer: false
                failure_handler: authentication_handler
                success_handler: authentication_handler
            remember_me:
                lifetime: 604800
                key: 3aafe9fde8cc6ec0d6e25e5bc2d143b3
            logout:       true
            anonymous:    true
    

     access_control:
         - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/admin/, role: ROLE_ADMIN }`

Plik Piorun/HomeSiteBundle/Reources/config/services.yml

  `services:
           authentication_handler:
                 class: 'FOS\UserBundle\Handler\AuthenticationHandler'
                 arguments: ["@service_container"]`

Stworzony został Handler sprawdzający czy przesłane zapytanie jest Ajaxowe. Jeżeli tak to odpowiednio dla przypadku niepowodzenia zwraca false dla poprawnego true.

   `<?php

        namespace FOS\UserBundle\Handler;

        use Symfony\Component\DependencyInjection\Container;
        use Symfony\Component\Security\Core\Exception\AuthenticationException;
        use Symfony\Component\HttpFoundation\Request;
        use Symfony\Component\Security\Core\SecurityContextInterface;
        use Symfony\Component\HttpFoundation\RedirectResponse;
        use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
        use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
        use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
        use Symfony\Component\HttpFoundation\JsonResponse;

        class AuthenticationHandler implements AuthenticationSuccessHandlerInterface,       AuthenticationFailureHandlerInterface
         {

            public function __construct(Container $container)
            {
    
                 $this->container = $container;
            }

            public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
            {
              if ($request->isXmlHttpRequest()) {

               return new JsonResponse(array('result' => false));
            }

            $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);

              $url = $request->headers->get('referer');

            return new RedirectResponse($url);
           }

           public function onAuthenticationSuccess(Request $request, TokenInterface $token)
          {

             if ($request->isXmlHttpRequest()) {

            return new JsonResponse(array('result' => true));
          }

          $key = '_security.main.target_path';
           if ($this->container->get('session')->has($key)) {
                $url = $this->container->get('session')->get($key);
            } else {
               $url = $this->container->get('router')->generate('piorun_home_site_adminpage');
            }
         return new RedirectResponse($url);
      }
     }`

Wywołanie metody logowania asynchronicznego może być następujące 


     `var data = {'_username':'administrator','_password':'1111' };

       $.ajax({
           type: "POST",
           url:'http://path/web/app_dev.php/login_check' ,
           data:data,
       });`