Auto_restrict : un fichier pour les verrouiller tous.
Pour continuer cette série sur la simplification des trucs ch****, je vous propose un fichier php qu'il suffit d'inclure dans une page pour en restreindre l'accès.
Comme de coutume, un cahier des charges:
- simplicité d'utilisation,
- configuration aisée,
- sécurité élémentaire (sessions)
- gestion automatique de l'expiration de session pour inactivité.
Les commentaires sont les bienvenus, je ne suis pas un expert de la sécurité ;) (et ça se voit )
[Edit du 27/10/2012]
Ajout d'une plus grande sécurisation via un snippet proposé par JérômeJ (thanxalot mon pot')
Le zip contient un exemple complet et simple:
- un fichier index.php qui appelle auto_restrict.php
- un fichier login_form.php contenant le formulaire servant à se logger
- auto_restrict.php (le fichier qu'il suffit d'inclure)
Lors de la première utilisation du script, Auto_restrict va proposer de créer le passe via un formulaire: on tape le passe voulu et le fichier pass.php est créé automatiquement avec le passe crypté.
Lorsqu'on charge ensuite la page qui appelle auto_restrict, cette dernière vérifie si les variables de session sont présentes et si elles sont correctes.
Afin d'éviter de se faire pécho sa session, j'ai ajouté une variable contenant toutes les infos de l'utilisateur (ip+navigateur) cryptée; j'ai récupéré les fonctions de cryptage sur info-3000.com merci au passage .
Si un problème est détecté, on dégage les variables de session éventuelles, on la détruit, on include le formulaire de login et on arrête tout.
Quand on remplit le formulaire et qu'on l'envoie, c'est encore auto_restrict qui prend la main et gère la connexion: si les login/passe correspondent à ceux fournis en config, on crée la session, sinon, on considère qu'il y a un problème... et on include le formulaire
session_start();// ------------------------------------------------------------------ // configuration // ------------------------------------------------------------------ $auto_restrict['error_msg']='Erreur - impossible de se connecter.';// utilisé si on ne veut pas rediriger $auto_restrict['encryption_key']='abcdef';// clé pour le cryptage de la chaine de vérification $auto_restrict['session_expiration_delay']=1;//minutes $auto_restrict['login']='login'; // caractères alphanum + _ et . $auto_restrict['redirect_error']='index.php';// si précisé, pas de message d'erreur // --------------------------------------------------------------------------------- // sécurisation du passe: procédure astucieuse de JérômeJ (http://www.olissea.com/) @include('pass.php'); if(!isset($auto_restrict['pass'])){ if(isset($_POST['pass'])){ # Création du fichier pass.php $salt = md5(uniqid('', true)); file_put_contents('pass.php', '<!--?php $auto_restrict["salt"] = '.var_export($salt,true).'; $auto_restrict["pass"] = '.var_export(hash('sha512', $salt.$_POST['pass']),true).'; ?-->'); include('login_form.php');exit(); } else{ # On affiche un formulaire invitant à rentrer le mdp puis on exit le script include('login_form.php');exit(); } } // --------------------------------------------------------------------------------- // ------------------------------------------------------------------ // ------------------------------------------------------------------ // gestion de post pour demande de connexion // si un utilisateur tente de se loguer, on gère ici // ------------------------------------------------------------------ if ($_POST){log_user($_POST['login'],$_POST['pass']);} // ------------------------------------------------------------------ // si pas de demande de connexion on verifie les vars de session // et la duree d'inactivité de la session // si probleme,on include un form de login. // ------------------------------------------------------------------ if (!is_ok()){session_destroy();include('login_form.php');exit();} // ------------------------------------------------------------------ // demande de deco via la variable get 'deconnexion' // ------------------------------------------------------------------ if (isset($_GET['deconnexion'])){log_user($_POST['login'],$_POST['pass']);} // ------------------------------------------------------------------
Pour la partie fonctions:
function id_user(){ // retourne une chaine identifiant l'utilisateur que l'on comparera par la suite // cette chaine cryptée contient les variables utiles sérialisées $id=array(); $id['REMOTE_ADDR']=$_SERVER['REMOTE_ADDR']; $id['HTTP_USER_AGENT']=$_SERVER['HTTP_USER_AGENT']; $id['session_id']=session_id(); $id=serialize($id); return $id; }function is_ok(){ // vérifie et compare les variables de session // en cas de problème on sort/redirige en détruisant la session global $auto_restrict; $expired=false; if (!isset($_SESSION['id_user'])){return false;} if ($_SESSION['expire']<time()){$expired=true;} $sid=Decrypte($_SESSION['id_user'],$auto_restrict['encryption_key']); $id=id_user(); if ($sid!=$id || $expired==true){// problème return false; }else{ // tout va bien //on redonne un délai à la session $_SESSION['expire']=time()+(60*$auto_restrict['session_expiration_delay']); return true; } } function log_user($login_donne,$pass_donne){ //cree les variables de session global $auto_restrict; if ($auto_restrict['login']==$login_donne && $auto_restrict['pass']==hash('sha512', $auto_restrict["salt"].$pass_donne)){ $_SESSION['id_user']=Crypte(id_user(),$auto_restrict['encryption_key']); $_SESSION['login']=$auto_restrict['login']; $_SESSION['expire']=time()+(60*$auto_restrict['session_expiration_delay']); return true; }else{ exit_redirect(); return false; } } function redirect_to($page){header('Location: '.$page); } function exit_redirect(){ global $auto_restrict; @session_unset(); @session_destroy(); if ($auto_restrict['redirect_error']&&$auto_restrict['redirect_error']!=''){//tester sans la deuxième condition redirect_to($auto_restrict['redirect_error']); }else{exit($auto_restrict['error_msg']);} } </pre> <p> </p> <p> Pour la page index.php</p> <pre class="brush:php;">
<?php // on include et c'est tout ! include('auto_restrict.php');
?> <div class='content'> <h1>Auto_restrict.php</h1><hr/> Vous etes <em>connecté!</em><br/> Durée d'inactivité avant déconnexion:<em> <?php echo $auto_restrict['session_expiration_delay']; ?> min.</em>
<fieldset> <a href='http://www.warriordudimanche.net/index.php' >Recharger cette page</a> <a href='http://www.warriordudimanche.net/?deconnexion=ok' class="deco">DECONNEXION</a> </fieldset>
</div>
On peut toujours complexifier le tout en
- sécurisant les données post,
- en faisant un ban provisoire des ip+navigateur qui cherchent à se logger sans succès trop de fois,
- en gérant plusieurs logins/mdp (via un fichier xml ou une BDD...)
Toutefois, je ne voulais pas compliquer l'utilisation sans raison.
Comme toujours, le zip est par là et la démo ici (login=login et pass=pass !)
❝ 19 commentaires ❞
Fil RSS des commentaires de cet article
✍ Écrire un commentaire
les commentaires relevant du SPAM seront filtrés et dégagés direct...