2012-05-14 49 views
6

我使用FOSRestBundle在防火墙内进行ajax json调用。一切似乎都很好,除了在会话超时发生时Im无法处理。现在它在这种情况下重定向到login_check,返回html而不是json到客户端。是否有会话超时a.k.a没有登录的symfony2事件/处理程序

我知道,并在我的应用程序中使用success_handler和failure_handler。我找不到处理授权失败的内置处理程序,例如会话超时。

在FOSRestBundle内有什么东西可以帮助解决这个问题,或者在Symfony2中没有看到什么?

回答

5

是的,Symfony提供了处理异常的可能性。您必须创建一个事件监听器,该监听器以高优先级观察kernel.exception事件。创建一个事件处理程序是这样的:

<?php 
namespace Acme\Bundle\MyBundle\EventListener; 

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use Symfony\Component\Security\Core\Exception\AccessDeniedException; 
use Symfony\Component\Security\Core\Exception\AuthenticationException; 

class AjaxAuthenticationListener 
{ 
    public function onKernelException(GetResponseForExceptionEvent $event) 
    { 
     $request = $event->getRequest(); 

     $format = $request->getRequestFormat(); 
     $exception = $event->getException(); 
     if ('json' !== $format || (!$exception instanceof AuthenticationException && !$exception instanceof AccessDeniedException)) { 
      return; 
     } 

     $response = new JsonResponse($this->translator->trans($exception->getMessage()), $exception->getCode()); 
     $event->setResponse($response); 
     $event->stopPropagation(); 
    } 
} 

现在,你有你的service.yml的一个的注册事件处理程序,如:

kernel.listener.ajax_authentication_listener: 
    class: Acme\Bundle\MyBundle\EventListener\AjaxAuthenticationListener 
    tags: 
     - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 250 } 

注意priority参数,使用告诉Symfony在它自己的处理程序之前执行处理程序,处理程序的优先级较低。

而在你的前端,你可以注册一个jQuery的事件处理程序,它会重新加载页面上的这样一个错误。

$(document).ready(function() { 
    $(document).ajaxError(function (event, jqXHR) { 
     if (403 === jqXHR.status) { 
      window.location.reload(); 
     } 
    }); 
}); 

查看this gist仅供参考。