Im using the FOSRestBundle to make ajax json calls within a Firewall. Everything seems to be working great, with the exception that Im not able to to handle when a session timeout has occurred. Right now it's redirecting to login_check in this scenario, returning html rather than json to the client.
Im aware, and use success_handler and failure_handler's within my app. I cannot find a built in handler for dealing with authorisation failures, such as session timeout.
Is there something within the FOSRestBundle that can help address this, or something Im not seeing within Symfony2?
Yes, Symfony offers the possibility to handle exceptions. You have to create an event listener which observes the kernel.exception
event with a high priority. Create an event handler like this:
<?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();
}
}
Now you have to register your event handler in one of your service.yml's, like this:
kernel.listener.ajax_authentication_listener:
class: Acme\Bundle\MyBundle\EventListener\AjaxAuthenticationListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 250 }
Note the priority
parameter, used to tell Symfony to execute the handler before its own handlers, which have a lower priority.
And on your frontend you can register an event handler for jQuery, which reloads the page on such an error.
$(document).ready(function() {
$(document).ajaxError(function (event, jqXHR) {
if (403 === jqXHR.status) {
window.location.reload();
}
});
});
See this gist for reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With