Classe de session et d'authentification

Contenu du snippet

Ceci est une classe simple qui se charge de gérer les sessions des visiteurs sur un site ainsi que leur authentification.
les visiteur (authentifiés ou non) sont considéré en ligne pendant 15 minutes.

Table MySQL :

CREATE TABLE `users` (
`id` bigint(20) NOT NULL auto_increment,
`username` varchar(10) NOT NULL default '',
`password` varchar(255) NOT NULL default '',
`email` varchar(255) NOT NULL default '',
`date_inscr` bigint(20) NOT NULL default '0',
`activate_key` varchar(255) NOT NULL default '',
`actif` enum('0','1','2','3') NOT NULL default '0',
`last_connect` bigint(20) NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `activate_key` (`activate_key`),
KEY `username` (`username`)
)

INSERT INTO `users` VALUES (-1, 'invité', '','', 0, '0', '3', 0);

CREATE TABLE `sessions` (
`sessionId` varchar(255) NOT NULL default '',
`user_id` bigint(20) NOT NULL default '0',
`last_maj` bigint(20) NOT NULL default '0',
`ip` varchar(15) NOT NULL default '',
PRIMARY KEY (`sessionId`),
KEY `last_maj` (`last_maj`)
)

==========================
Cette classe est prévu pour fonctionner avec un classe d'abstraction de base de données (en l'occurence celle de malalam disponible ici : http://www.phpcs.com/codes/CLASSE-BASE-DONNEES-EX-AVEC-MYSQL-MSSQL-PHP5_35671.aspx

Source / Exemple :


<?php
//          Classe gérant les sessions et l'authentification sur le site          //
////////////////////////////////////////////////////////////////////////////////////

class Session
{
  	private $session_id
        private $db;
  	private $msg_error;
  	private $Connected = false;
  	private $session;
        private $user;
  	
  	//--------------------------------------------------//
	// Constructeur de la classe
	// 
	function __construct($session_id, $db)
  	{
		$this->session_id = $session_id;
		$this->db = $db;
		
		// On provoque le ménage des sessions épuisé
		$this->CleanSessionsObsolete();	  
			  
		// On recherche les informations sur la session.
		if($this->SessionExist())
		{
		  	// La session est déja existante. On mets à jour la date de dernier accés pour garder le visiteur.
		  	$this->db->query("UPDATE sessions SET last_maj='".date('U')."' WHERE sessionId='".$this->session_id."';");
		  	if($this->session['user_id'] != '-1')
			{
				$this->Connected = true; 
				$this->db->query("UPDATE users SET last_connect='".date('U')."' WHERE id='".$this->session['user_id']."';");
			}
		}
		else
		{
		  	// Aucune session existante. On en crée une avec le compte invité.
		  	$this->db->query("INSERT INTO sessions (sessionId, user_id, last_maj, ip) VALUES('".$this->session_id."', '-1', '".date('U')."', '".$_SERVER['REMOTE_ADDR']."')");
		}
		$this->RefreshData();  
	}
	
	//--------------------------------------------------//
	// Méthode magique __GET
	// Retourne le contenu de la variable demandé
	private function __GET($nm)
	{
	  	$this->RefreshData();
		if(isset($this->$nm))
			$r = $this->$nm; 
		else
			throw new Exception('Session::__GET('.$nm.') => impossible de trouver l\'objet demandé.');
		
		return $r;
	}
	
	//--------------------------------------------------//
	// Vérifie si le numéro de session est déja enregistré dans la base
	// Retourne true si la session est déja dans la base, sinon retourne false.
	private function SessionExist()
	{
	  	$requete = $this->db->query("SELECT * FROM sessions WHERE sessionId='".$this->session_id."';");
	  	$nb = $this->db->num_rows($requete);
	  	if($nb == 0)
	  	{
	    	return false;
		}
		else
		{
			$this->session = $this->db->fetch_assoc($requete);
			return true;
		}
	}
	
	//--------------------------------------------------//
	// Récupère les données depuis la base de données.
	// 
	private function RefreshData()
	{
	  	$this->session = null;
	  	$this->user = null;
		  
		// On récupère les informations sur la session
		$requete1 = $this->db->query("SELECT * FROM sessions WHERE sessionId='".$this->session_id."';");
		$this->session = $this->db->fetch_assoc($requete1);
		 
		// On récupère les informations sur l'utilisateur  
		$requete2 = $this->db->query("SELECT * FROM users WHERE id='".$this->session['user_id']."';");
		$this->user = $this->db->fetch_assoc($requete2);
	}
	
	//--------------------------------------------------//
	// Nettoie les sessions considérée comm fermée
	// 
	private function CleanSessionsObsolete()
	{
		$interval = date('U') - 15*60;
		$requete = $this->db->query("DELETE FROM sessions WHERE last_maj<='".$interval."';");
	}
	
	//--------------------------------------------------//
	// Authentifie un utilisateur (var1 = nom d'utilisateur, var2 = mot de passe)
	// Retourne un booléen pour la réussite de l'authentification.
	// Si l'authentification réussi : affecte Connected à true. Si elle rate insert la raison dans msg_error.
	public function AuthUser($username_input, $password_input)
	{
	  	$this->msg_error = '';
	  	$username_input = mysql_real_escape_string(traiteVar($username_input, 0));
	  	$password_input = mysql_real_escape_string(traiteVar($password_input, 0));
	  	
		// On selectionne dans la base le champs correspondant au nom d'utilisateur.
	  	$requete = $this->db->query("SELECT * FROM users WHERE username='".$username_input."';");
	  	if($this->db->num_rows($requete) == 1)
	  	{
	    	$user = $this->db->fetch_assoc($requete);
			// L'utilisateur existe, peut-il se connecter
	    	if($user['actif'] != 1)
			{
			  	// L'utilisateur n'est pas actif, est suspendu ou 
			  	//la personne essai de se connecter avec le compte invité
			  	switch($user['actif'])
			  	{
			    	case 0:
			    		// L'utilisateur n'est pas activé
			    		$this->msg_error = 'Ce compte n\'est pas actif. Consulter le mail qui vous à été envoyé pour plus de renseignement.';
	    				break;
	    			case 2:
			    		// L'utilisateur n'est pas activé
			    		$this->msg_error = 'Ce compte à été suspendu par un administrateur. Vous ne pouvez donc pas vous connecter.';
	    				break;
	    			case 3:
			    		// L'utilisateur n'est pas activé
			    		$this->msg_error = 'Ce compte ne permet pas de connexion authentifiée.';
	    				break;
			  	}
				return false;
			}
			else
			{
			  	// L'utilisateur est bien actif.
			  	// On vérifie maintenant si le mot de passe est bon
			  	$pcrypt_input = crypt($password_input, $username_input);
			  	if($pcrypt_input == $user['password'])
			  	{
			    	// Tout est ok on mets à jour la session pour prendre en compte les modifications
			    	$this->db->query("UPDATE sessions SET user_id='".$user['id']."' WHERE sessionId='".$this->session_id."';");
			    	$this->RefreshData();
					$this->Connected = true;
					$this->db->query("UPDATE users SET last_connect='".date('U')."' WHERE id='".$this->session['user_id']."';");
			    	return true;
				}
				else
				{
				  	// Le mot de passe est incorrect
		  			$this->msg_error = 'Utilisateur ou mot de passe incorrect.';
	    			return false;
				}
			}	    	
		}
		else
		{
		  	// L'utilisateur n\'existe pas
		  	$this->msg_error = 'Utilisateur ou mot de passe incorrect.';
	    	return false;
		}
	}
	
	//--------------------------------------------------//
	// Déconnecte un utilisateur
	// 
	public function DisconnectUser()
	{
	  	$this->RefreshData();
	  	if($this->session['user_id'] != -1)
	  	{
	    	$this->db->query("UPDATE sessions SET user_id='-1' WHERE sessionId='".$this->session_id."';");
	    	$this->Connected = false;
	    	$this->RefreshData();
		}
	}
	
	//--------------------------------------------------//
	// Récupère des satistiques sur les session courantes
	//
	public function GetStatsSession(&$data)
	{
	  	$requete = $this->db->query("SELECT * FROM sessions");
	  	$res = $this->db->fetch_assoc($requete);
	  	
	  	$data[] = $this->db->num_rows($requete);
	}
}
?>

<?php
// Utilisation
session_start();
$session = new Session(session_id(), $db);

// On authentifie
if($session->AuthUser($_POST['username'], $_POST['pass']))
{
  echo 'Authentification réussi';
}
else
{
  // L'authentification à échoué
  echo $session->msg_error;
}

if($session->Connected)
{
    echo 'Vous êtes connecté';
}
?>

Conclusion :


Les mots de passe doivent être cryptés dans la base de données suivant cette méthode :

$pass_crypt = crypt($password, $username);

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.