Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a symfony2 event/handler for session timeout a.k.a not logged in

Tags:

symfony

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?

like image 293
MadManMonty Avatar asked May 14 '12 12:05

MadManMonty


1 Answers

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.

like image 103
naitsirch Avatar answered Oct 31 '22 00:10

naitsirch