2012-05-14 51 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僅供參考。