protect

Protéger l’accès à une page

En utilisant les notions de classe, et de session nous allons apprendre à authentifier un utilisateur, afin de lui permettre d’accéder à une page protégée.

 

 

Etape 1: Réalisation de la page d’authentification

La première étape va consister à réaliser notre formulaire d’authentification qui se trouvera sur cette page qu’on apellera : »index.php« .

<html>
        <head>
            <title>Identification</title>
        </head>
        <body>
            <form action="index.php" method="post">
                <label>Login</label><input type="text" name="login"/>
                <label>MDP</label><input type="password" name="mdp"/>
                <button type="submit">Valider</button>
            </form>
        </body>
    </html>

Cette page et volontairement simplifiée, j’y ai enlevé les éléments propres à xHTML, etc… On se retrouve donc avec un formulaire assez simple composé de deux champs « login » et « mdp » puis d’un bouton pour soumettre notre formulaire.

Les variables seront transmises avec la méthode post étant donné que faire apparaître un mot de passe en clair dans une URL ne serait pas très sécurisant (voir pas du tout^^).


Etape 2 : La classe Identification

On aurait pu concevoir ce tutorial sans l’utilisation de classe, mais dans une optique pour vous de pouvoir par la suite ajouter quelques fonctionnalités supplémentaires (gestion de compte, etc…) j’ai préférer choisir la programmation objet.

Voici notre classe que l’on nommera Identification et qui se retrouvera dans le fichier « class.Identification.php« . Voici l’ossature de cette classe pour que vous puissiez y voir un peu plus clair avant de commencer:

<?php
class Identification{

		public function __construct(){
			session_start();
		}
		public function connexion(){
		}
		public function deconnexion(){
		}
		public function verificationAcces(){
		}

}
?>

Cette classe va donc posséder 3 méthodes (fonctions): Une qui nous permettra de nous connecter (en fonction de la variable $_POST passée en paramètre), une pour se déconnecter et enfin une dernière pour vérifier si l’on est bien connecté. Vous remarquerez aussi une méthode particulière : le constructeur (__construct) qui est éxécutée automatique dés que l’on instancie un objet de cette classe. Cette méthode ne fait ici rien de particulier si ce n’est démarrer une session qu’on réutilisera par la suite.

Etape 3 : La connexion

Nous allons donc maintenant remplir la méthode connexion (prenant en paramètre la superglobale $_POST). Voici son code:

public function connexion($tab){
			if(!empty($tab['login'])){
				$login = $tab['login'];
				$mdp = $tab['mdp'];
				include('config.php');
				$connect = mysql_connect(MYHOST, MYUSER, MYPASS)  or die ('Identifiants incorrects');
				mysql_select_db(MYDB) or die ('Base de données incorrecte');
				$requete = 'SELECT id,login,mdp FROM utilisateurs WHERE login="'.mysql_real_escape_string($login).'" AND mdp="'.mysql_real_escape_string(md5($mdp)).'"';
				$result = mysql_query($requete);
				$utilisateur = mysql_fetch_assoc($result);
				if(mysql_num_rows($result) == 1){
					$_SESSION['connecte'] = true;
					$_SESSION['id'] = $utilisateur['id'];
					header('Location:protege.php');
					return true;
				}
				return false;
				mysql_close($connect);
			} else{
				return true;
			}
		}

Cette méthode va donc renvoyer true si l’utilisateur n’a rien rempli ou s’est bien connecté, sinon false si ses identifiants sont incorrects. Dans un premier temps il va falloir tester si le login est vide avec la fonction empty(). S’il ne l’est pas on éxécute le reste de notre fonction.

Ensuite nous nous connectons à une base de donnée pour vérifier le couple login/mdp. Pour cela on effectue une requête de type SELECT avec une condition WHERE ou les 2 paramètres doivent être respectées.

table des utilisateurs

Pour vous connecter à votre base de données, vous avez besoin de vos identifiants. Je les ai donc placé dans un fichier config.php, qui correspond pour moi à ca:

<?php
define("MYHOST","localhost");
define("MYUSER","root");
define("MYPASS","");
define("MYDB","snoupix_tutoriaux");
?>

La requête utilise 2 fonctions particulières:

  • mysql_real_escape_string() qui permet de sécuriser votre application en évitant les attaques par Injection SQL.
  • md5() qui crypte le mot de passe en MD5, étant donné que les mots de passes ne sont pas stockés dans la base de données en durs, il est nécessaire de crypter le mot de passe dans notre requête. Par ailleurs si vous utilisez la table montrée un peu plus haut et disponnible dans le code source, le mot de passe correspond à « toto ».

Après avoir éxécuté notre requête et vérifié qu’elle nous renvoit bien une seule ligne. Nous initialisons notre variable superglobale de session en précisant aussi l’identifiant du connecté (cela peut être utile de le récupérer après dans les autres pages…). Enfin si tout s’est bien passé, nous redirigeons notre utilisateur vers la page protégée en question.

Etape 4: Et dans l’index.php?

Il ne reste plus qu’à tester cette méthode dans notre page index.php, en n’oubliant pas d’inclure notre classe Identification, on en arrive à ceci:

<?php
	include('class.Identification.php');
	$connexion =  new Identification();
	$affichage = '';
	if(!$connexion-&gt;connexion($_POST)){
		$affichage = '
&lt;p class="error"&gt;MDP ou Login incorrects

';
	}
?>
<html>
    <head>
        <title>Identification</title>
    </head>
    <body>
        <?=$affichage?>
        <form action="index.php" method="POST">
            <label>Login</label><input type="text" name="login"/>
            <label>MDP</label><input type="password" name="mdp"/>
            <button type="submit">Valider</button>
        </form>
    </body>
</html>

Voilà tout ce que l’on à faire est d’afficher un message d’erreur si la méthode renvoit false :)

Etape 5 : Protéger les pages

C’est bien gentil tout ça, mais ca n’empêche pour l’instant pas les gens d’accéder à notre page protege.php en y accédant en tapant l’URL. C’est là qu’intervient notre méthode verificationAcces().

public function verificationAcces(){
    if(!$_SESSION['connecte'] == true)
         header('Location:index.php');
}

Cette méthode est en fait très simple nous testons juste si la variable $_SESSION['connecte'] vaut bien true.

Enfin dans notre page protege.php, il suffit simplement d’instancier la classe Identification et d’éxécuter la méthode verificationAcces() comme ceci:

<?php
	include('class.Identification.php');
	$identification = new Identification();
	$identification-&gt;verificationAcces();

    echo 'Ouaw! Des infos confidentielles &lt;a href="index.php?deconnexion=true" _mce_href="index.php?deconnexion=true"&gt;Se déconnecter&lt;/a&gt;';
?>

Etape 6: Et moi j’en ai marre, je veux me déconnecter

Il nous manque plus que la méthode deconnexion() à réaliser. Cette méthode est relativement simple, elle utilise 2 fonctions: session_destroy(), qui détruit la session et unset() qui vide et détruit une variable :

public function deconnexion(){
	session_destroy();
	unset($_SESSION);
}

Pour éxécuter cette méthode vous l’avez peut être remarqué dans le script précédent, j’utilise une URL qui pointe vers index.php avec une variable de types GET : index.php?deconnexion=true.

Enfin je teste dans ma page si la variable $_GET['deconnexion'] == true auquel cas, il faudra éxécuter notre méthode.

if(isset($_GET['deconnexion'])){
   if($_GET['deconnexion'] == true){
	$connexion-&gt;deconnexion();
   }
}

Ce tutorial touche à sa fin, n’hésitez pas à laisser des commentaires, si vous souhaitez quelques éclaircissements ;) .

19 commentaires

S'abonner au RSS des commentaires
  1. esty
    Posté le 21/02/2011 à 9h48

    bjr à vous quand je teste ce code çà me donne des erreurs de ce genre :

    warning :mysql_fetch_assoc() :supplied argument is not valid mysql result resource

    warning :mysql_num_rows() :supplied argument is not valid mysql result resource

    je ne compends pas trop parce ke j’ai bien passé les arguments en parametres et verifié avec votre code mais çà ne donne rien
    svp pouvez vous m’eclaicir??

  2. Hamza.Design
    Posté le 01/11/2010 à 23h19

    Salut je voudrais savoir ou mettre mon MOT DE PASSE ET Pseudo car il me dit mot de passe incorrect et merci encore

  3. ZiOu
    Posté le 18/07/2010 à 14h44

    Ok !! Merci ! smile

  4. François
    Posté le 18/07/2010 à 12h11

    Comme il a été dit, le script en soit est assez sécurisé. Après ca dépent du mot de passe utilisé, si tu utilises Azerty, bien sur ca se hack très rapidement. Faut-il encore avoir accès à la Base de donnnées…

  5. ZiOu
    Posté le 17/07/2010 à 23h24

    Bonjour !

    D’après ce que je lis plus haut, la méthode donnée via ce tutoriel n’est pas très bonne. A t-il était modifié ? Est-ce quand même correct ?

    Merci par avance !

  6. doudou1973
    Posté le 04/01/2010 à 8h55

    Merci pour cet excellent tuto.

    Je suis débutant et j’essaye d’appliquer les conseil que l’on me donne ds mon site de démarrage.

    à bientôt dans un autres tuto wink

  7. Dilem
    Posté le 16/07/2009 à 17h39

    Et bien disons qu’une suite de 15 char composée de chiffres/lettres/char_spé EST IMPOSSIBLE a trouver avec les dicos actuels.

    Donc, cela prouve ce que je voulais dire : La faille ce n’est pas MD, c’est le password en lui même.
    Car au final, si l’utilisateur prend comme password ‘toto’, qu’il soit en MD5/Sha-1/Sha-256/Sha-512 eu autres hash function, il sera quand même dans les dicos smile

  8. François
    Posté le 16/07/2009 à 1h14

    Non non il suffit de mettre un mot de passe intelligent^^

    Ah non j’ai pas réussi à décrypter (en tout cas sur les scripts qu’on peut trouver sur le Net…) . Si c’est pas un mot dans le dico c’est tout de suite plus dur^^

  9. Dilem
    Posté le 15/07/2009 à 18h00

    @Ryo :

    Le fait que les passwords soient hashé en MD5 n’est pas une faille en soit.

    Tiens, je te met au défis de retrouver la password d’origine de ce hash :

    16b300c7cefa728190d4dd905e6824ae

    Bon courage smile

    Cependant, SHA-1 est quand même vivement conseillé.

    Bon je stop mon troll.
    Très bon tuto soit dit au passage.

  10. majdi105
    Posté le 27/06/2009 à 22h37

    svp je veux un script comme ca

  11. François
    Posté le 10/04/2009 à 17h57

    Ouai je comprends et c’est sur que c’est beaucoup plus sécurisé comme méthode, surtout si le mot de passe choisi est bidon…

    Sinon je suis pas très calé niveau hash et cryptage mais sha1 est apparemment un peu plus fiable que MD5…

    Merci pour ton gros grain de sel!! Je mettrais à jour ce tuto bientôt!

  12. Ryo
    Posté le 10/04/2009 à 16h05

    Je vois un sacré problème de sécurité dans votre scripts.
    Bien que vous stockez les mots de passe en md5 dans la base de donnée, rien n’empêche s’il l’on récupère par un moyen quelconque la base de tenté un brute force en essayant de retrouvé les bons md5 à partir d’une liste dictionnaire ou de site spécialisé dans les tables de conversion md5 <> mot de passe

    Une méthode beaucoup plus robuste consiste à créer la clé md5 à partir du mot de passe et d’un grain de sel généré aléatoirement à la création de l’utilisateur. Ce grain de sel devra comporter un bon nombre de caractères (au moins 30). Ensuite on stocke ce grain de sel dans la base et quand on teste si le mot de passe est bon on teste en fait mot de passe + grain de sel. Du coup la clé est md5 est généré sur plus de 30 caractères et l’attaque à partir de dictionnaire ou en brute force devient impossible avec la puissance des ordinateurs actuels.
    Exemple :
    1) l’utilisateur s’enregistre, il choisit son mot de passe "love"
    2) on génère un grain de sel de façon aléatoire d’au moins 30 caractères "un_grain_de_sel_aléatoire_de_bonne_taille"
    3) on calcule la clé md5 de "loveun_grain_de_sel_aléatoire_de_bonne_taille"
    4) on stock dans la base de donnée la clé md5 et le grain de sel.

    Quand l’utilisateur s’identifie:
    1) on teste si la clé md5 enregistrée est égal à $mot_de_passe + grain_de_sel_aléatoire_enregistré_pour_cet_utilisateur

    Cela permet de caché beaucoup plus fortement les mot de passe si la base de donnée tombe entre de mauvaises mains.

  13. john david
    Posté le 30/03/2009 à 15h39

    chez moi ca ne marchait pas :
    http://www.commentcamarche.net/faq/sujet-1391-php-notice-undefined-index
    la notice est reportée selon la configuration du serveur
    et le raccourci ne marchait pas non plus, rien ne s’affichait héhé

  14. Francois
    Posté le 30/03/2009 à 15h21

    Ah ah c’est bien tenté mais ca marche quand meme!!!
    pour le premier ca renvoit faux si la variable il ne la connait pas… … mais bon c’est vrai que c’est mieux d’écrire comme tu l’as fais…

    Pour le 2eme truc <?=?> c’est un raccourci, et pas besoin de isset puisque dans tous les cas ma variable est initialisé.

  15. nanana
    Posté le 30/03/2009 à 12h33

    ma solution:

    if (isset($_GET['deconnexion'])){
    if(($_GET['deconnexion'] == true) ){
    $connexion->deconnexion();
    }
    }

    et pis ton $affichage t’as fait du caca aussi (l14 de l’index)

    <?php if(isset($affichage)){echo $affichage;}?>

  16. nanana
    Posté le 30/03/2009 à 12h26

    si tu veux mon avis
    # if($_GET['deconnexion'] == true){
    # $connexion->deconnexion();
    # }

    c’est codé comme un cochon francois!
    il faut tester les valeurs! du coup chez moi ça fait des erreurs et je pleure devant "Notice: Undefined index: deconnexion"

  17. shafos01
    Posté le 27/03/2009 à 22h26

    Bonjour ce tutoriel est super mais j’aimerais qu’il aille uen suite; le formulaire d’inscriptions.svp merci de me répondre a mon email:shafos02@gmail.com
    merci

  18. styledrive1
    Posté le 23/03/2009 à 19h31

    je suis un debutant dans le web design et la programmation php/mysl
    merci pour vos tutos
    samir du maroc

  19. ThibZ
    Posté le 09/03/2009 à 17h04

    Très bonne idée de commencer avec de la programmation objet, je m’y suis mis un peu plus tôt et je me rend compte au fur et à mesure de sa puissance en PHP.
    Merci pour le tuto smile

Laisser un commentaire

Votre e-mail ne sera jamais publié ni communiqué. Les champs obligatoires sont indiqués par *

*
*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>