Brave publisher PUBLISHER
Développeur web Front-End dans l'Oise - Gary Deshayes

Symfony Event Subscriber | Restriction d'une plage ip avec un Event Subscriber

Développeur web Front-End dans l'Oise - Gary Deshayes <--Translation

Crée le : samedi 14 novembre 2020

Ajout d'un Event Subscriber sous Symfony avec restriction de plage IP

Dans le cadre du tutoriel, nous allons mettre en place une restriction de plage IP pour autoriser certaines IP, mais vous pouvez utiliser les Event subscriber
dans n'importe quel cas. Un Event subscriber permet d'executer du code avant de rentrer dans notre route d'un controller par exemple, il nous permet de vérifier certaines
choses tel que la connexion en token, et toutes autres sortes de manipulations.

Ajout du fichier SecureIpSubscriber.php

Il vous faut commencer par ajouter un dossier EventSubscriber dans le dossier src de votre projet Symfony (Ou bien où vous le souhaitez mais c'est plus rapide ici).
Et ensuite ajouter le fichier suivant :

<?php

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;

class SecureIpSubscriber implements EventSubscriberInterface
{
    public function onKernelController($event)
    {
        // Ajouter votre code ici
    }

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::CONTROLLER => 'onKernelController',
        ];
    }
}

Vous pouvez voir que notre classe SecureIpSubscriber implemente obligatoirement l'interface EventSubscriberInterface
Et que grace à la fonction static getSubscribedEvents, nous connaissons l'event sur lequel la classe écoute, il existe plusieurs events Symfony
Le code qui sera executé lors de l'écoute sur cet event est présent dans la fonction onKernelController, nous allons donc voir comment restreindre les ip !

Définition des plages ip et ajout d'une fonction de tri

Pour restreindre les plages ip nous devons d'abord connaitre quelles plages restreindre :

class SecureIpSubscriber implements EventSubscriberInterface
{
    private $ips = array(
        array('deb' => '125.1.0.1', 'fin' => '125.158.3.254'),
        array('deb' => '192.168.5.1', 'fin' => '192.168.160.254'),
    );

    /**
    Code ...
    */
}

Nous ajoutons donc une variable privée qui permet de définir deux plages ip, nous pourrions en ajouter autant que voulue.
Et ensuite nous avons besoin d'une fonction (qui n'est pas de moi) qui va permettre de trier les ip dans notre tableau.

    //Check plage ip
    private function verifPlageIP($IP, $PlageIP)
    {
        $result = true;
        $tabIP = explode(".", $IP);
        if (is_array($PlageIP)) {
            foreach ($PlageIP as $valeur) {
                $tabPlageIP[] = explode(".", $valeur);
            }
            for ($i = 0; $i < 4; $i++) {
                if (($tabIP[$i] < $tabPlageIP[0][$i]) || ($tabIP[$i] > $tabPlageIP[1][$i])) {
                    $result = FALSE;
                }
            }
        } else {
            $tabPlageIP = explode(".", $PlageIP);
            for ($i = 0; $i < 4; $i++) {
                if (($tabIP[$i] != $tabPlageIP[$i])) {
                    $result = FALSE;
                }
            }
        }
        return ($result);
    }

Et une fois nos plages définies et la fonction verifPlageIp dans notre classe, nous pouvons écrire le code dans le onKernelController :

    //On check l'ip seulement sur la route de l'api
    public function onKernelController($event)
    {
        //On check l'ip seulement sur la route de l'api
        if ($event->getRequest()->get('_route') == "api") {
            $ip = $_SERVER['REMOTE_ADDR'];
            $valid = false;
            // localhost
            if ($ip == '::1' || $ip == '127.0.0.1') {
                $valid = true;
            } else {
                foreach ($this->ips as $plage) {
                    $valid = $this->verifPlageIP($ip, $plage);
                    if ($valid === true) break;
                }
            }

            if ($valid === false) {
                exit();
            }
        }
    }

Dans mon cas nous pouvons voir que j'ai restreint l'ip pour une seule route, mais il est possible de supprimer cette condition pour que cela soit applicable à l'ensemble de 
l'application, ou bien en rajouter d'autres au choix.
Nous vérifions donc si l'ip est localhost ou bien dans une plage ip, si c'est bon on continue dans notre route qui pourrait nous retourner des données d'une API et dans
le cas contraire le code est exit et la personne ne reçoit rien.

Event Subscriber Symfony, Restriction de plage ip

Nous pouvons voir dans le profiler de Symfony que nous rentrons bien dans notre nouvel Event Subscriber, il est possible de dump dedans pour débuguer !

Ce tutoriel est maintenant terminé, merci d'avoir lu et n'hésitez pas à le partager !

Articles récents :

Symfony 5 | Retourner une image via une route d'un controller

Symfony

Crée le : mercredi 1 septembre 2021

VueJS 3, ExpressJS 4.17 | Upload et redimensionnement d'une image

Javascript Framework JS

Crée le : samedi 28 novembre 2020

Symfony Event Subscriber | Restriction d'une plage ip avec un Event Subscriber

Symfony

Crée le : samedi 14 novembre 2020

Angular, ExpressJS | Authentification JWT avec Angular 10 et ExpressJS 4 (MySQL)

Javascript SQL Framework JS

Crée le : dimanche 20 septembre 2020

Symfony, Excel, CSV | Générer un fichier CSV pour Excel avec Symfony

Symfony

Crée le : jeudi 6 août 2020

Symfony FormType ChoiceType | Radio button valeur par défaut dans un FormType

Symfony

Crée le : dimanche 26 juillet 2020

Doctrine, Symfony | Différence entre deux dates sous MySQL (Jour, mois, années...)

Symfony SQL

Crée le : jeudi 18 juin 2020

JavaScript, jQuery et Regex | Sécuriser un mot de passe en temps réel avec JS

Javascript jQuery

Crée le : lundi 23 mars 2020

Symfony, Doctrine | Récupérer les anciennes données d'un formulaire FormType

Symfony

Crée le : vendredi 14 février 2020

jQuery, Webpack et Symfony | Appeler jQuery dans vos fichiers twig

Symfony Bugs

Crée le : dimanche 26 janvier 2020