• Créer une connexion sécurisée avec Codeigniter

    image de l'aticle Créer une connexion sécurisée avec Codeigniter

    Codeigniter est un framework légé libre écrit en PHP construit en MVC.

    Ce tutoriel à pour but de vous montrer comment réaliser une entrée dans un espace voulant être sécurisé avec un identifiant et un mot de passe. il fonctionne avec les cookies "helper" et la librairie "encrypt" de Codeigniter.

    P.S. : le code n'est pas très documenté mais expliqué dans ce tuto dans les grandes lignes, donc si vous avez des questions n'hésitez pas à laisser un commentaire. ;-).

    Configuration de Codeigniter

    Tout d'abord nous allons faire quelques petites modifications dans le fichier config/config.php du dossier application/ de votre framework. Recherchez dans ce fichier :

    $config['encryption_key'] = '';

    Et saisissez la clé de votre choix, par exemple : 1C8DS7C4DSC8DS4CSD564CS6DVDSH. Ne faites pas un copier/coller de cette clé hein :-(?

    $config['cookie_prefix'] = '';

    Mettez ici le préfixe des cookies qui sera utilisé pour les nommer, par exemple xsqiocsq_

    Mettez sur TRUE cette variable :

    $config['global_xss_filtering'] = TRUE;

    Cela permettra de filtrer les valeurs $_GET, $_POST et les $_COOKIES contre les attaques cross-site scripting. Codeigniter offre ce genre de sécurité par défaut, il faut juste l'activer donc profitons-en.

    Pour utiliser les fonctions base_url() ou site_url() dans les vues (pratique pour créer les liens), vous devez renseigner dans ce fichier $config['base_url'] :

    $config['base_url'] = 'http://www.votre-site.com/';

    Et pour finir, mettez aussi cette variable sur TRUE :

    $config['rewrite_short_tags']

    Ce qui nous permettra d'écrire :

    <?=$var ?>

    Au lieu de ça :

    <?php echo $var ?>

    Le code sera un peu plus lisible dans la vue du modèle MVC de Codeigniter.

    Ensuite éditez le fichier autoload.php toujours dans le dossier config/ et ajoutez le chargement de la librairie "database". Recherchez la ligne $autoload['libraries'] et ajoutez :

    $autoload['libraries'] = array('database');

    Cette librairie sera ainsi disponible directement dans vos controllers et modèles sans la charger à chaque fois.
    Dans ce meme fichier, ajoutez aussi url "helper" qui est pratique pour la construction des liens.

    $autoload['helper'] = array('url');

    Fini les configurations!

    Les controllers

    Pour faire une connexion sécurisée nous allons créer un dossier modules/ dans notre dossier application/ et y ajouter le controlleur ADMINISTRATOR_Controller.php. Tous les controlleurs nécessitant une authentification hériteront de ce controlleur. En faisant les controles d'authentifications ne seront plus nécessaires dans chaque controlleur mais dans un seul. Voici le contenu du fichier :

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

    class ADMINISTRATOR_Controller extends CI_Controller {
        
        private $_cookie = array(
                       // 'name'   => '',
                       // 'value'  => '',
                       'expire' => '86500',
                       // 'domain' => '.some-domain.com',
                       'path'   => '/',
                       // 'prefix' => '',
                   );
        
        private $_cookie_id_name = "189CDS8CSDC98JCPDSCDSCDSCDSD8C9SD"; // nom d'un cookie
        private $_cookie_id_password = "1C89DS7CDS8CD89CSD7CSDDSVDSIJPIOCDS"; // nom d'un cookie
        
        function __construct()
        {
            parent::__construct();
            $this->load->helper('cookie');
            $this->load->library('encrypt');
            $this->load->model('administrator_model');
            
            if ($this->input->post('identifiant', TRUE) && $this->input->post('password', TRUE))
            {
                if ($this->administrator_model->validate($this->input->post('identifiant'), $this->input->post('password')))
                {
                    $cookies_identifiant = $this->_cookie;
                    $cookies_identifiant['name'] = $this->_cookie_id_name;
                    $cookies_identifiant['value'] = $this->encrypt->encode($this->input->post('identifiant'));
                    // $cookies_identifiant['domain'] = "";
                    $cookies_identifiant['prefix'] = $this->config->item('cookie_prefix');
                    set_cookie($cookies_identifiant);

                    $cookies_password = $this->_cookie;
                    $cookies_password['name'] = $this->_cookie_id_password;
                    $cookies_password['value'] = $this->encrypt->encode($this->input->post('password'));
                    // $cookies_identifiant['domain'] = "";
                    $cookies_password['prefix'] = $this->config->item('cookie_prefix');
                    set_cookie($cookies_password);
                    
    // Tout est ok, ont redirige vers la page d'accueil de l'admin
                    redirect(site_url("admin/index"));
                }
                else
                { // Mauvais identifiant, ont redirige vers la page de connexion
                    redirect(site_url("admin/connexion"));
                }
            }
            elseif (get_cookie($this->config->item('cookie_prefix').$this->_cookie_id_name, TRUE) &&
                    get_cookie($this->config->item('cookie_prefix').$this->_cookie_id_password, TRUE))
            {
                $mail = $this->encrypt->decode(get_cookie($this->config->item('cookie_prefix').$this->_cookie_id_name));
                $password = $this->encrypt->decode(get_cookie($this->config->item('cookie_prefix').$this->_cookie_id_password));
                if ($this->administrator_model->validate($mail, $password) == FALSE)
                    redirect(site_url("admin/connexion")); // Mauvais identifiant, ont redirige vers la page de connexion
            }
            elseif ($this->router->fetch_class() != "connexion")
            {
                redirect(site_url("admin/connexion")); // Mauvais identifiant, ont redirige vers la page de connexion
            }
        }
    }

    ADMINISTRATOR_Controller vérifie si des variables attendues sont passées en mode $_POST et vérifie leur valeur via le modèle "administrator_model" que nous allons voir plus loin, si les valeurs sont exactes et que l'utilisateur existe bien il créé les cookies dont il va se servir pour garder la navigation en cours active et ne pas demander à chaque fois une authentification. Les cookies sont ensuite analysés à chaque demande de page nécessitant une authentification.

    Remarque : ce controlleur nécessite que vous ayez obligatoirement un controlleur "Connexion" qui hérite de cette classe et il doit se trouver dans controllers/admin/connexion sinon les redirection en cas de mauvaise authentification "redirect(site_url("admin/connexion"));" ne fonctionneront pas et afficheront une page 404.


    Nous allons maintenant écrire nos 2 controlleurs dans le dossier application/controllers/admin/. Si ce dossier n'existe pas, créez-le.
    Ajoutez un fichier nommé connexion.php et un fichier nommé index.php.

    Le fichier connexion :

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

    include(APPPATH . 'modules/ADMINISTRATOR_Controller.php'); // chemin vers le controlleur parent
    class Connexion extends ADMINISTRATOR_Controller {
        
        function __construct() {
            parent::__construct(); // On appel le constructeur de ADMINISTRATOR_Controller car
    // c'est lui qui va vérifier les données et accepter la page appelée ou non.
        }
        
        function index() {
            $this->load->view('admin/index');
        }
    }

    Le controlleur index.php est aussi simple et identique à celui de connexion car ce sera dans cet exemple une façon de vérifier si tout est ok et qu'ont puissent accéder aux méthodes de ce controlleur uniquement si ont est connecté.

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

    include(APPPATH . 'modules/ADMINISTRATOR_Controller.php'); // chemin vers le controlleur parent
    class Index extends ADMINISTRATOR_Controller {
        
        function __construct() {
            parent::__construct(); // On appel le constructeur de ADMINISTRATOR_Controller car
    // c'est lui qui va vérifier les données et accepter la page appelée ou non.
        }
        
        function index() {
            $this->load->view('admin/index');
        }
    }

    Le modèle

    Voici le fichier modèle, créez-le dans le dossier models/ de Codeigniter :

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

    class Administrator_model extends CI_Model {
        
        private $_table = "user";
        
        function __construct() {
            $this->load->library('encrypt');
        }
        
        public function validate($mail, $password) {
            if (($passwd_crypt = $this->_getUser($mail)) !== FALSE)
                return (bool) ($password == $passwd_crypt);
            return false;
        }
        
        private function _getUser($mail) {
            $user = $this->db->select(array('mail', 'password'))->get_where($this->_table, array('mail' => $mail))->row();
            if (isset($user->password))
                return $this->encrypt->decode($user->password);
            return false;
        }
    }

    Le mot de passe utilisateur est crypté grâce à la librairie "encrypt" de Codeigniter. La méthode "validate()" du modèle récupère donc l'identifiant saisi et recherche s'il existe dans la base de données, s'il existe il retourne le mot de passe, le décode et le compare au mot de passe saisi par l'utilisateur.

    Pour utiliser une base de données dans Codeigniter n'oubliez pas de remplir les informations de connexion dans le fichier config/database.php

    $active_group = 'default';
    $active_record = TRUE;

    $db['default']['hostname'] = 'localhost';
    $db['default']['username'] = 'utilisateur';
    $db['default']['password'] = 'motdepasse';
    $db['default']['database'] = 'basededonnees';
    $db['default']['dbdriver'] = 'mysql';
    $db['default']['dbprefix'] = '';
    $db['default']['pconnect'] = TRUE;
    $db['default']['db_debug'] = TRUE;
    $db['default']['cache_on'] = FALSE;
    $db['default']['cachedir'] = '';
    $db['default']['char_set'] = 'utf8';
    $db['default']['dbcollat'] = 'utf8_general_ci';
    $db['default']['swap_pre'] = '';
    $db['default']['autoinit'] = TRUE;
    $db['default']['stricton'] = FALSE;

    Les vues

    Pas besoin de faire grand chose dans les vues, ont va juste afficher un peu de contenu. Créer un dossier admin/ dans le dossier views/ et ajoutez le fichier connexion.php avec ce contenu :

    <!DOCTYPE html>
    <html lang="en">
    <head>

    <meta charset="utf-8">

    </head>
    <body>
        <h1>Login</h1>
        <div id="body">
            <form action="<?=site_url("admin/connexion")?>" method="post" >
                <p>Identifiant :</p>
                <code><input type="text" name="identifiant" value="" /></code>
                <p>Mot de passe :</p>
                <code><input type="password" name="password" value="" /></code>
                
                <input type="submit" name="login" value="Connexion">
            </form>
        </div>
    </body>
    </html>

    et créez le fichier index.php au même endroit en y mettant ce contenu :

    <!DOCTYPE html>
    <html lang="en">
    <head>

    <meta charset="utf-8">

    </head>
    <body>
        <h1>Vous êtes connecté!</h1>
        <div id="body">
    Félicitation!
        </div>
    </body>
    </html>

    La base de données

    Créez et nommez la base de données puis insérez cette table :

    CREATE TABLE IF NOT EXISTS `user` (
      `id` int(2) NOT NULL AUTO_INCREMENT,
      `mail` varchar(35) NOT NULL,
      `password` mediumtext NOT NULL,
      `date_add` datetime NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

    Pour ajouter un utilisateur dans cette base de données, vous devez au préalable crypter avec la librairie "encrypt" de Codeigniter un mot de passe. Pour faire cela faites fonctionner un script dans une vue ou un controlleur de votre choix et appelez-le via votre navigateur web. Par exemple, vous avez un controlleur par défaut dans Codeigniter qui est welcome.php contenant ceci :

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

    class Welcome extends CI_Controller {

        /**
         * Index Page for this controller.
         *
         * Maps to the following URL
         *         http://example.com/index.php/welcome
         *    - or -  
         *         http://example.com/index.php/welcome/index
         *    - or -
         * Since this controller is set as the default controller in
         * config/routes.php, it's displayed at http://example.com/
         *
         * So any other public methods not prefixed with an underscore will
         * map to /index.php/welcome/<method_name>
         * @see http://codeigniter.com/user_guide/general/urls.html
         */
        public function index()
        {
            $this->load->view('welcome_message');
        }
    }

    /* End of file welcome.php */
    /* Location: ./application/controllers/welcome.php */

    Ajoutez dans la méthode index() ceci :

    $this->load->library('encrypt');
    $mdp = $this->encrypt->encode("votremotdepasse");
    die($mdp);

    Et appelez la page d'accueil de votre site pour afficher le mot de passe crypté. Ensuite ajoutez une ligne dans la table user avec votre mail, mot de passe crypté et la date d'ajout. Exemple :

    INSERT INTO user (`mail`, `password`, `date_add`) VALUES ('votre@mail.com', 'DGADYFM+C2DFV9F8oihcsdovcsdv5lMxASBSZgBiATk=', '2013-05-30 16:00:00');

    Voilà, s'il manque des choses ou si vous avez des constations à faire sur ce script n'hésitez pas à me contacter ou à laisser un commentaire. Bon courage...

5 commentaires

ghilo  05-08-2013

Merci beaucoup pour ce tuto :)
mais j'ai pas compris quand est ce que on appel la page de l'authentification ? merci

kouame  15-08-2013

tres bon tuto comment gerer la deconnexion

Espinasse  14-09-2013

Avec beaucoup de retard voici ma réponse. Dsl pour l'absence...
Pour gérer la déconnexion il faut créer un lien dans ton back-office vers le controller de ton choix et ajouter une méthode à qui supprimerait les cookies préalablement enregistrés lors de la connexion (delete_cookie("name")). Voir Cookie. ;-)

reine  05-09-2014

j'ai beaucoup apressier votre tuto

Laissez un commentaire

* Votre e-mail ne sera jamais utilisé ou donné à un tiers

Recherche

Catégories

Newsletters

Archives