PROJET AUTOBLOG


Warrior du Dimanche

Site original : Warrior du Dimanche

⇐ retour index

Auto_restrict 2.0: un fichier pour les verrouiller tous.

jeudi 13 juin 2013 à 11:04

Aujourd'hui, histoire de ressuciter un peu, je vous propose une amélioration de auto_restrict, le fichier php qu'il suffit d'inclure dans une page pour en restreindre l'accès.

J'ai beaucoup utilisé ce petit fichier dans mes projets mais il lui manquait une feature importante: la coche "rester connecté". 

Désormais, il gère un cookie dont on définit la durée et le nom dans la config et qui éviter d'avoir à chaque fois le formulaire de login.

En cas de déconnexion, le cookie est viré. 

J'ai également amélioré le rendu du formulaire sur les mobiles, ajouté la possibilité de choisir son login lors de la création et déplacé la variable login dans le fichier pass.php.

 

 

 


 

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 login et le passe via un formulaire: on tape les identifiants de connexion voulus et le fichier pass.php est créé automatiquement avec le passe crypté et le login.

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 ou si le cookie est présent.

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 ^^

	// ------------------------------------------------------------------
	// configuration	
	// ------------------------------------------------------------------
	$auto_restrict['error_msg']='Erreur - impossible de se connecter.';// utilisé si on ne veut pas rediriger
	$auto_restrict['cookie_name']='auto_restrict';// nom du cookie
	$auto_restrict['encryption_key']='abcdef';// clé pour le cryptage de la chaine de vérification
	$auto_restrict['session_expiration_delay']=1;//minutes
	$auto_restrict['cookie_expiration_delay']=360;//days
	$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/)
	if(file_exists('pass.php')) include('pass.php');
	if(!isset($auto_restrict['pass'])){
		if(isset($_POST['pass'])&&isset($_POST['login'])&&$_POST['pass']!=''&&$_POST['login']!=''){ # Création du fichier pass.php
			$salt = md5(uniqid('', true));
			file_put_contents('pass.php', '');
			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 (isset($_POST['login'])&&isset($_POST['pass'])){
		log_user($_POST['login'],$_POST['pass']);
		if (isset($_POST['cookie'])){setcookie($auto_restrict['cookie_name'],sha1($_SERVER['HTTP_USER_AGENT']),time()+$auto_restrict['cookie_expiration_delay']*1440);}
	}

	// ------------------------------------------------------------------	
	// 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('dis','connect');}
	// ------------------------------------------------------------------	
	

Pour la partie fonctions:

	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($_COOKIE[$auto_restrict['cookie_name']])&&$_COOKIE[$auto_restrict['cookie_name']]==sha1($_SERVER['HTTP_USER_AGENT'])){return true;}
		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();
		setcookie($auto_restrict['cookie_name'],'',time()+1);
		if ($auto_restrict['redirect_error']&&$auto_restrict['redirect_error']!=''){
				redirect_to($auto_restrict['redirect_error']);
		}else{exit($auto_restrict['error_msg']);}
	}


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à .