Dynamic-Mess.com


"The world is a dynamic mess of jiggling things..."

Gérer les session et l'authentification avec PHP5

Article posté le 21-11-2013 dans la catégorie PHP

Les trois principales methodes d'authentification en PHP ne sont pas égales en efficacité.

L'identification de l'utilisateur par son adresse IP peut notamment poser problème si plusieurs utilisateurs ont la même adresse IP. L'authentificaton par le protocole HTTP est quant à elle plus adaptée à la protection de répertoires entiers plutôt qu'au suivi des utilisateurs. A cela il faut ajouter que la gestion en est laissée au navigateur de l'utilisateur, ce qui poser des soucis en cas d'ordinateurs partagés.

Avec PHP5, rien de plus de simple que de gérer des sessions utilisateurs. Grâce aux variables globales dédiées à cet effet, vous pourrez gérer facilement les utilisateurs qui doivent accéder à un contenu nécessitant une identification.

Il est à noter que ce processus utilise un cookie. Cette méthode est d'ailleurs préférable, mais cela peut poser problème si le navigateur refuse les cookies. On peut aussi utiliser le système de réecriture automatique des liens,que nous n'aborderons pas ici.

1- Un exemple (très) bas de gamme

Commençons avec un exemple un peu pourri histoire de comprendre les mécanismes.

La première étape est d'utiliser la fonction session_start() qui indique à votre serveur d'activer la gestion de session. Elle sera ainsi démarrée ou reprise. Vous pouvez ainsi manipuler la variale globale $_SESSION, qui est un tableau. Vous pourrez stocker facilement ce que vous voulez comme informations (attention : pas de mot de passe!) afin de gérer l'accès à votre contenu. L'id de session est généré automatiquement et envoyé via un header, pour être stocké dans un cookie. A noter que vous pouvez modifier le nom de la session (par défaut PHPSESSID) soit dans php.ini soit avec la méthode :

session_name();

De plus j'insiste sur le fait toujours de toujours utiliser des sessions par cookie, et non par URL.

A- Connexion

Dans notre exemple, l'utilisateur se connecte via un formulaire. La première étape (que nous n'aborderons pas ici), est de vérifier que le mot de passe encodé est bien égal à ce qui se trouve dans la base de données des utilisateurs, pour le pseudo correspondant. Là non plus rien de sorcier.

Dans le fichier PHP qui gère cette étape, il faut rajouter, en cas de cohérance identifiant/mot de passe, le stockage des variables utilisateurs. Par exemple ici, si l'authentification est ok, stocker deux variables, le pseudo, et le statut de connexion "Ok".

if(Connexion($_POST['Pseudo'], $MotDePasse)) // on vérifie que les identifiants sont bons
{
    $_SESSION['Pseudo'] = $_POST['Pseudo'];  // Je stocke dans le tableau, un champ "Pseudo", avec le pseudo à l'intérieur
    $_SESSION['ConnectOK'] = true; // Statut de connexion à "Ok"
    header("Location:index.php"); // redirection vers la page d'accueil, ou un espace perso...
}

A présent, la session est en route.

B - Gestion de l'accès

A présent, quand l'utilisateur voudra accéder à du contenu nécessitant la connexion ou que vous désirez par exemple afficher une partie du menu réservée aux membres, vous pouvez utilisez cette condition :

if (isset($_SESSION['ConnectOK'])&&($_SESSION['ConnectOK'] == true)) // Si la variable existe, et qu'elle contient ce qu'il faut...
{
    // Ici faites ce que vous voulez : affichage de la page par exemple
}

Voilà, rien de sorcier...

A noter que PHP garantie un identifiant de session unique. Il peut être retrouvé par la fonction :

session_id()

mais également dans la constante SID.

Concernant la durée de validité du cookie de session, il expire à la fermeture du navigateur.

C- Mettre fin à la session

Pour des raisons de sécurité ou par pratique, vous pouvez vouloir mettre fin à la session, soit manuellement (bouton déconnexion), ou encore automatiquement (durée maximale de session). Pour cela, il faut utiliser la fonction session_destroy. Mais attention de bien faire le nécessaire pour détruire aussi le cookie. Voir l'exemple sur la doc de PHP ici.

2- Des choses un peu plus sérieuses...

Maintenant, voyons un exemple de qualité plus professionnelle et mieux adapté à un espace d'authentification.

Faisons donc un petit rappel: quand vous utilisez session_start(), PHP va démarrer ou reprendre la session en cours. La session est donc gérée par un cookie de session, automatiquement envoyé au client. Ce cookie contient ni plus ni mois qu’un identifiant de session, unique. Cela n’a strictement rien à voir avec l’authentification de l’utilisateur: même s’il n’est pas connecté à la zone à l’accès contrôlée, un cookie de session est émis. Quant aux données de session, elles sont stockées sur le serveur, pour une durée paramétrée dans le fichier php.ini, et modifiable depuis le code PHP, pour la durée du script.

Les données de session sont stockées sur le serveur, donc quand l’utilisateur arrive avec son cookie, on “ressort” ses données de session. Vous l’avez compris, tout est lié à ce fameux identifiant de session.

Dans l’exemple ci-dessus, nous avons choisi la solution de facilité: quand l’utilisateur se connecte à cette zone à accès restreint, nous stockions une donnée dans sa session. Cela nous permettait de savoir qu’il est connecté à chaque fois qu’il revenait. Mais cette solution n’est pas géniale.

En effet, si les données de session sont importantes, il est recommandé d’utiliser un cookie supplémentaire (à celui de l’identifiant de session) quand il s’agit de mettre en place une fonction “se souvenir de moi” pour vos utilisateurs qui se connectent à votre site.

Voici comment cela doit fonctionner:

Si par contre l’utilisateur ne coche pas l’option “Se souvenir de moi”, là on dira au serveur de supprimer les données de session au bout d’environ une heure*, et au navigateur d’oublier son identifiant de session au bout d’un heure (rien ne vous garantie qu’il le fera, donc n’oubliez pas la première opération).

Ce mécanisme permet ainsi de mettre en place une notion de sécurité en profondeur: même si quelqu’un de mal intentionné à accès à la base, il ne pourra rien faire car le token est hashé. De plus, il est recommandé d’utiliser HTTPS pour éviter le vol de cookie.

Pour ce dernier point, vous pouvez effectuer d’autres opérations et stocker d’autres informations dans le cookie, afin d’essayer de repérer des choses suspectes. Je vous conseille vivement de lire mon article traitant de la sécurité avec PHP.

*”Environ” car le garbage collector de PHP passe quand il veut. En fait vous dites à PHP de garder les données de session pour au maximum la durée précisée.

Résumons donc:

Quelques fonction utiles pour gérer une durée limite de session:

// On dit au serveur de ne pas conserver les données de sessions plus d'une heure (il se peut qu'il les détruise avant, car passage du garbage collector imprévisible)
ini_set('session.gc_maxlifetime', 3600);
// Dit au client "STP, si possible, oublie ton id de session au bout d'un heure" (Rien ne vous garantit qu'il le fera...)
session_set_cookie_params(3600);
// On démarre la session ou on la reprend si elle existe
session_start();

3- Un peu de sécurité

Savez-vous qu'avec un vol de cookie on peut se faire passer pour quelqu'un d'autre... Voici donc quelques mesures de sécurité à envisager, dans certains cas... Elles doivent être combinées dans l'idéal.


Tweet
comments powered by Disqus