Page 1 sur 1
Gestion Multi-Utilisateurs
Posté : 27 févr. 2006, 10:42
par envahisseur
Bonjour,
Je développe une application en PHP5 et je souhaiterai pouvoir controler les login des utilisateurs. Pour cela j'utilise les sessions PHP mais je rencontre une difficulté que je n'arrive pas à résoudre.
Je souhaiterai qu'un utilisateur ne puisse se connecter qu'une seule fois à la fois avec le même login. J'y arrive avec un bouton de deconnexion en mettant à jour ma BDD mais si l'utilisateur ferme son navigateur, je perd l'information et mon utilisateur apparaut toujours connecté dans ma base.
Je vous remercie par avance pour votre aide précieuse.
David.
Re: Gestion Multi-Utilisateurs
Posté : 27 févr. 2006, 11:31
par starkeus
Bonjour,
Je souhaiterai qu'un utilisateur ne puisse se connecter qu'une seule fois à la fois avec le même login. J'y arrive avec un bouton de deconnexion en mettant à jour ma BDD mais si l'utilisateur ferme son navigateur, je perd l'information et mon utilisateur apparaut toujours connecté dans ma base.
Nous avons eu le même soucis et la seule solution potable fut de créer un système de frame donc l'une sera invisible et porteuse de l'évènement onBeforeUnload. Lorsque l'utilisateur ferme la fenêtre, un message apparaît (tu ne peux pas vraiment le personnaliser juste ajouter quelques lignes) et selon l'option choisie par l'utilisateur tu lances ton script php de déconnexion "propre".
Gestion Multi-Utilisateurs
Posté : 27 févr. 2006, 12:33
par envahisseur
Je te remercie mais pourrais-tu être plus précis?
De plus il me semble que l'evénement OnBeforeOnload est un événement seulement géré par IE et pas par Firefox?
David.
Re: Gestion Multi-Utilisateurs
Posté : 27 févr. 2006, 14:23
par starkeus
Je te remercie mais pourrais-tu être plus précis?
De plus il me semble que l'evénement OnBeforeOnload est un événement seulement géré par IE et pas par Firefox?
David.
J'essaierai d'être un peu plus précis quand j'en aurais le temps, promis

Et je te confirme cet évènement fonctionne aussi sous FF

Posté : 27 févr. 2006, 15:01
par starkeus
Bon je précise:
Alors ton application va contenir 2 frames, exemple :
<frameset rows="*,18">
<frame name="main" frameborder="0" src="main.php" title="contenu"></frame>
<frame name="footer" frameborder="0" noresize="noresize" scrolling="no" src="footer.php" title="bas de page"></frame>
</frameset>
Ma frame footer doit récupérer les 2 évènements
onBeforeUnload et
onUnload:
<body onBeforeUnload="return message();" onUnload="confirmLogOut();">
L'évènement
onBeforeUnload aura lieu car l'utilisateur va fermer la fenêtre. Alors une pop up de confirmation générique lui posera la question s'il souhaite vraiment fermer la fenêtre. S'il dit non alors la fenêtre ne se ferme pas, s'il répond oui alors le navigateur va fermer la fenêtre et donc déclencher l'évènement
onUnload. Et c'est à partir de cet évènement que tu pourras lancer un script php et de notre côté on a pris le parti d'utiliser Ajax pour réaliser la déconnexion et fermer la fenêtre.
Posté : 27 févr. 2006, 15:31
par naholyr
Toute tentative de gestion des session côté client sera au mieux buggée, au pire non sécurisée.
Pour éviter les "fantomes" (c'est le terme employé pour les sessions terminées mais que le serveur croit toujours ouverte, ce qui arrive parfois sur IRC si vous pratiquez un peu), le seul moyen c'est un timeout de session.
Il faut gérer côté serveur une variable "dernière fois que l'utilisateur X a été vu actif" (typiquement dans la table "users" de la base de données). Si ça date de plus de X minutes, on considère l'utilisateur comme déconnecté. Bien sûr il faut que X soit supérieur au session_timeout du php.ini sinon on prend le risque qu'un utilisateur puisse ouvrir plusieurs sessions (il aura été considéré comme déconnecté par le serveur alors qu'il ne l'est pas réellement puisque la session est toujours active).
Concrètement en très court :
// au début d'index.php
session_start();
if ($_SESSION['connected']) {
// on met à jour la dernière fois qu'il a été vu actif
mysql_query('UPDATE users SET dernieractif = NOW() WHERE username = "'.$_SESSION['username'].'"');
}
// dans login.php
$res = mysql_query('SELECT 1 FROM users WHERE DATE_ADD(dernieractif, INTERVAL '.$timeout.' MINUTE) > NOW() AND username = "'.$_POST['username'].'"';
if (mysql_num_rows($res) > 0) {
die('vous êtes déjà connecté');
}
// dans logout.php
mysql_query('UPDATE users SET dernieractif = "0000-00-00 00:00:00" WHERE username = '.$_SESSION['username']);
Posté : 27 févr. 2006, 16:18
par starkeus
Toute tentative de gestion des session côté client sera au mieux buggée, au pire non sécurisée.
Je ne vois pas en quoi c'est bugué et non sécurisé?

Posté : 27 févr. 2006, 16:24
par naholyr
S'il me prend l'envie d'accéder à ton site en passant outre les frames (typiquement parce que j'ai mis une page particulière en favori en passant par le clic droit, et donc le frameset sautera la prochaine fois que je viendrai), ou pire : si j'ai désactivé javascript (environ 5% des navigateurs actuellement), le principe ne fonctionnera pas.
Et on se retrouvera avec des fantomes éternels.
Posté : 27 févr. 2006, 16:33
par starkeus
S'il me prend l'envie d'accéder à ton site en passant outre les frames (typiquement parce que j'ai mis une page particulière en favori en passant par le clic droit, et donc le frameset sautera la prochaine fois que je viendrai), ou pire : si j'ai désactivé javascript (environ 5% des navigateurs actuellement), le principe ne fonctionnera pas.
Et on se retrouvera avec des fantomes éternels.
Ok je vois. Cela dépend du contexte alors car dans mon cas il s'agit d'une application intranet (et pour
envahisseur aussi) donc on peut se permettre d'avoir certaines exigences de configuration.
Gestion Multi-Utilisateurs
Posté : 27 févr. 2006, 19:21
par envahisseur
Merci pour votre aide.
Je vais regarder les deux scenarios de pres.
David.
Posté : 27 févr. 2006, 22:42
par nicolas
Pour ma part, je gèrerais la connexion unique en base de données. Tu stockes l'identifiant de session en plus du fait qu'il est déjà loggé. S'il essaie de se reconnecté tu lui précises qu'il est déjà connecté et tu supprimes alors l'ancienne session s'il persiste sinon tu refuses la nouvelle connexion.
Posté : 28 févr. 2006, 01:33
par fab
S'il me prend l'envie d'accéder à ton site en passant outre les frames (typiquement parce que j'ai mis une page particulière en favori en passant par le clic droit, et donc le frameset sautera la prochaine fois que je viendrai), ou pire : si j'ai désactivé javascript (environ 5% des navigateurs actuellement), le principe ne fonctionnera pas.
Et on se retrouvera avec des fantomes éternels.
Ok je vois. Cela dépend du contexte alors car dans mon cas il s'agit d'une application intranet (et pour
envahisseur aussi) donc on peut se permettre d'avoir certaines exigences de configuration.
le problème est le même si un utilisateur de l'intranet a mis dans des marques-pages une url sans la frame. Je deconseille aussi cette méthode je préfère gèrer ça avec des timestamps. Quand l'utilisateur affihce une page on stock l'heure d'affichage, pour voir les membres en ligne je fixe une durée par exemple 10 minutes et je cherche dans la BD les utilisateurs qui ont consultés une page dans les 10 dernières minutes.
C'est le principe de phpbb entre autre
Posté : 28 févr. 2006, 10:06
par starkeus
Alors oui et non

c'est vrai que dans son cas, il veut juste bien gérer les session en cas de déconnexion. Mais dans le mien, il s'agissait d'une exigence client qui souhaitait avoir une confirmation avant déconnexion que ce soit via le lien de déconnexion classique ou via la fermeture de la fenêtre...Et à part cette technique je ne vois aucune autre manière de gérer ce cas.

Gestion Multi-Utilisateurs
Posté : 01 mars 2006, 10:26
par envahisseur
Bonjour,
Finalement j'ai fait un mixte des deux: un champ mis à 1 dans la base données lorsqu'un utilisateur se connecte, ensuite je gère l'événement unbeforeunload qui me permet de le déconnecter s'il ferme son navigateur sans cliquer sur le bouton de déconnexion.
J'ai aussi rajouter un timeout au niveau de l'interface me permettant de gérer les sessions qui expirent. Dans ce cas, si le timeout au niveau du serveur est de X minutes, à X-5 minutes je lui affiche une alerte lui demandant de rafraichir sa femetre et au bout de X minutes, je le déconnecte automatiquement.