2015-02-23 2 views
4

Я пытаюсь выполнить аутентификацию AJAX с помощью FOSUserBundle.FOSUserBundle AJAX Вход с Symfony2 (маршрутизация)

Я создал каталог Handler с AuthenticationHandler class:

<?php 

namespace BirdOffice\UserBundle\Handler; 

use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\Routing\RouterInterface; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 
use Symfony\Component\Security\Core\Exception\AuthenticationException; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Security\Core\SecurityContextInterface; 
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; 
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; 

class AuthenticationHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface 
{ 
    private $router; 
    private $session; 

    /** 
    * Constructor 
    * 
    * @param RouterInterface $router 
    * @param Session $session 
    */ 
    public function __construct(RouterInterface $router, Session $session) 
    { 
     $this->router = $router; 
     $this->session = $session; 
    } 

    /** 
    * onAuthenticationSuccess 
    * 
    * @param Request $request 
    * @param TokenInterface $token 
    * @return Response 
    */ 
    public function onAuthenticationSuccess(Request $request, TokenInterface $token) 
    { 
     // if AJAX login 
     if ($request->isXmlHttpRequest()) { 

      $array = array('success' => true); // data to return via JSON 
      $response = new Response(json_encode($array)); 
      $response->headers->set('Content-Type', 'application/json'); 

      return $response; 

      // if form login 
     } else { 

      if ($this->session->get('_security.main.target_path')) { 

       $url = $this->session->get('_security.main.target_path'); 

      } else { 

       $url = $this->router->generate('home_page'); 

      } // end if 

      return new RedirectResponse($url); 

     } 
    } 

    /** 
    * onAuthenticationFailure 
    * 
    * @param Request $request 
    * @param AuthenticationException $exception 
    * @return Response 
    */ 
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) 
    { 
     // if AJAX login 
     if ($request->isXmlHttpRequest()) { 

      $array = array('success' => false, 'message' => $exception->getMessage()); // data to return via JSON 
      $response = new Response(json_encode($array)); 
      $response->headers->set('Content-Type', 'application/json'); 

      return $response; 

      // if form login 
     } else { 

      // set authentication exception to session 
      $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception); 

      return new RedirectResponse($this->router->generate('login_route')); 
     } 
    } 
} 

Я создал login Javascript function:

function login() { 
    $.ajax({ 
     type: "POST", 
     url: Routing.generate('check_login_ajax'), 
     dataType: 'json', 
     data: { 
      _username: $('#username').val(), 
      _password: $('#password').val(), 
      _remember_me: false, 
      _csrf_token: $('#_csrf_token').val() 
     } 
    }).done(function(data) { 
     console.log(data); 
    }).fail(function(data) { 
     console.log(data); 
    }); 
} 

В моих routingAjax.yml, я добавил следующие строки замещающей FOSUserBundle security route:

check_login_ajax: 
    pattern: /check_login_ajax 
    defaults: { _controller: FOSUserBundle:Security:check } 
    requirements: 
     _method: POST 
    options: 
     expose: true 

В м у глобального security.yml файл, я добавил check_path, success_handler и failure_handler частей:

firewalls: 
     main: 
      pattern: ^/ 
      form_login: 
       login_path: fos_user_registration_register 
       check_path:  check_login_ajax 
       success_handler: user.security.authentication_handler 
       failure_handler: user.security.authentication_handler 
       provider: fos_userbundle 
       csrf_provider: form.csrf_provider 
      logout: 
        path: fos_user_security_logout 
        target:/
      anonymous: true 

Мой первый вопрос заключается в следующем: AJAX вернуть это сообщение: «Invalid лексемы CSRF.» (но я посылаю хороший, сгенерированный на PHP, возможно, я пропустил что-то такое). Вот мой PHP код для него:

<?php 
    $csrfProvider = $this->container->get('form.csrf_provider'); 
    $csrfToken = $csrfProvider->generateCsrfToken('popUpUser'); 
?> 

Второго вопрос: моя страница Логина (не AJAX один) не работает больше, так как оригинальная трасса FOSUserBundle входа была перезаписана.

PS: Я вчера опубликовал сообщение: FOSUserBundle (login/register) + AJAX + Symfony2, но я плохо объяснил свою проблему. Извините заранее.

+0

Если вы используете symfony2.4, то генерация токена изменила использование 'security.csrf.token_manager' вместо' form.csrf_provider' – zizoujab

+0

Спасибо за помощь, я использую Symfony 2.6.4. Я просто заменяю следующее: ' container-> get ('form.csrf_provider'); $ csrfToken = $ csrfProvider-> generateCsrfToken ('popUpUser'); ? > ' By: ' Get ('security.csrf.token_manager'); $ csrfToken = $ csrf-> refreshToken ('popUpUser'); ?> ' Но у этого же сообщения об ошибке есть такое же сообщение об ошибке. –

ответ

5

Первый номер: вы : отправка недействительного токена CSRF. В Symfony 2.3 вы можете сгенерировать его с помощью {{ csrf_token('authenticate') }} внутри шаблона input шаблона шаблона: value.

Вторая проблема: не перезаписывайте маршрут, просто используйте оригинальный маршрут: fos_user_security_check.

В общем: если вы используете AuthenticationSuccessHandler простирающейся Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler вашего метода может выглядеть следующим образом:

public function onAuthenticationSuccess(Request $request, TokenInterface $token) 
{ 
    if ($request->isXmlHttpRequest()) { 
     return new JsonResponse(array('success' => true)); 
    } 

    return parent::onAuthenticationSuccess($request, $token); 
} 

ли что-то подобное для AuthenticationFailureHandler расширения Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler.

Смежные вопросы