Contrôle d’accès simple avec CodeIgniter

Une des choses redondantes dans un projet, c’est le contrôle d’accès. Savoir jusqu’où un utilisateur non connecté peut aller, ou même limiter les droits de certains utilisateurs.
Le truc basique c’est de checker soit dans le constructeur du contrôleur, soit dans chaque fonction du contrôleur si l’utilisateur a les droits suffisants pour continuer. Or lorsque le projet atteint une certaine ampleur, il devient vite contraignant et lourd de rajouter ce contrôle à chaque fonction.

Étendre la classe controller

Au début, je pensais créer un hook pre-controller mais toutes les fonctionnalités dont j’avais besoin n’étaient pas chargées. Du coup j’étends la classe controller afin que chaque contrôleur commence par checker l’accès avant d’aller plus loin.

Pour étendre la classe controller il faut créer un fichier /application/core/MY_Controller.php

<?php (defined('BASEPATH')) OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    public function __construct() {
        parent::__construct();

    }
}

Préparer les liens accessibles sans connexion

Ici je définis tous les liens ( controleur/fonction ) qui peuvent être accessibles sans connexion. Pour moi c’est plus simple dans ce sens, il est possible de faire l’inverse s’il y a plus d’endroits accessibles sans connexion qu’avec connexion.

<?php (defined('BASEPATH')) OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    protected $_no_access_control = array (
        'utilisateur/nouveau',
        'utilisateur/connexion'
    );

    public function __construct() {
        parent::__construct();

    }

}

Je créé donc un tableau avec les fonctions qui n’ont pas besoin de contrôle d’accès. C’est utile de mettre les fonctions car on peut très bien imaginer une fonction profil dans le contrôleur user, qui aurait besoin d’un contrôle d’accès.

Mise en place du contrôle d’accès

<?php (defined('BASEPATH')) OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

protected $_no_access_control = array (
        'utilisateur/nouveau',
        'utilisateur/connexion'
    );

    public function __construct() {
        parent::__construct();

        $this->_check_auth();
    }

    // Vérifie les authorisations
    private function _check_auth() {
        // Construction de l'uri
        $uri = $this->router->fetch_class() . '/' . $this->router->fetch_method();

        // Si la personne n'est pas connecté et qu'elle veut aller sur un lien non autorisé
        if ( ! $this->session->userdata('login') && ! in_array($uri, $this->_no_access_control) ){
            $this->_kick();
        }
    }

    // Redirige les requetes non authorisées
    private function _kick() {
        if ( $this->input->is_ajax_request() ) {
            $response = array('status' => 'disconnected');
            echo (json_encode($response));
            die();
        }
        else {
            redirect('accueil');
        }
    }
}

Voila tout est fait.

Explications:

A chaque chargement du contrôleur, on construit l’URI pour n’avoir que le contrôleur et sa fonction. On vérifie à partir de la session si la personne est connectée et si l’url qu’elle demande lui est autorisée. Avec cet exemple simple, un utilisateur non connecté peut accéder qu’aux liens présents dans le tableau. Pour tous les autres il doit être connecté. Lorsque l’utilisateur n’est pas accepté, il est redirigé directement vers l’accueil.

Maintenant c’est bien beau, mais il va falloir modifier chaque contrôleur afin de les étendre à partir de notre nouveau contrôleur de base.

class Utilisateur extends MY_Controller {

}

Conseil d’utilisation de ce système:

Si vous n’avez pas du tout besoin du contrôle d’accès dans votre contrôleur, vous créez votre contrôleur normalement ( extends CI_Controller ).

Si au moins une fonction de votre contrôleur a besoin du contrôle d’accès alors vous créez à partir de votre contrôleur étendu ( extends MY_Controller ).

Vus : 4017
Publié par Maxime CHAILLOU : 11