Question

Im building an In-House only web application based on Symfony2 and Sylius. My company has 4 different offices with static IP addresses, and I want to track which office a user is operating out of. Some employees move to different locations on different days, some users have laptops that travel from location to location within a day too. Location will need to be referenced for almost every page view involving writing to the database ( the application needs to know what location an event is happening at ).

Im looking for suggestions as to how to best store and reference this info. I will have a static list of IP addresses and offices they correspond to. This list can live in yml or a database table ( we anticipating adding locations at once a year pace, so editing this list can be a manual task ). Should this be something I just store in a session, or lookup every page load via $container->get('request')->getClientIp() in all my controllers, or create a Symfony2 ROLE and assign it with the user on login, or ? Other suggestions how to best accomplish this?

Im very new to Symfony2 still, so if there is an obvious place for this kind of logic, my apologies... I figured it would be somewhat unique since most public facing web-apps would not and perhaps in many cases should not track IP addresses the way I need to in this case... Thanks in advance.

Was it helpful?

Solution

You do not have to modify your controllers, just create an event listener and, on each request, do what you want to do.

To get the user, just inject the security context service and get the token. Then you can get the user if the request is behind a firewall.

Here is an example based on the official documentation (not tested and must be modified to fit on your project):

// src/Acme/DemoBundle/EventListener/AcmeRequestListener.php
namespace Acme\DemoBundle\EventListener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\Security\Core\SecurityContextInterface;

class AcmeRequestListener
{
    protected $sc;

    public function __construct(SecurityContextInterface $sc)
    {
        $this->sc = $sc;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) {
            // don't do anything if it's not the master request
            return;
        }

        if( null === ($token = $this->sc->getToken()) ) {
            // don't do anything if you are not behind a firewall
            return;
        }

        // do anything with $token to get the user and check he is authenticated
        $user = $token->getUser();

        // Client IP
        $ip = $event->getRequest()->getClientIp();
    }
}

And you service definition:

<!-- app/config/config.xml -->
<service id="kernel.listener.your_listener_name" class="Acme\DemoBundle\EventListener\AcmeExceptionListener">
    <argument type="service" id="security.context" />
    <tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" />
</service>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top