IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Interdire une deuxième connexion avec le même compte


Sujet :

Langage PHP

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut Interdire une deuxième connexion avec le même compte
    Bonjour

    J'utilise les sessions pour gérer les pages accessibles seulement aux utilisateurs qui sont inscrits.
    Mon service est payant et je ne veux pas qu'une seule personne s'inscrive et partage son identifiant. Je ne peux pas complètement empêcher ça, mais je veux au moins empêcher que 2 personnes se connectent avec le même identifiant en même temps. Je ne peux pas utiliser l'IP car je veux aussi empêcher que 2 postes sur la même IP se connectent en même temps.

    Sur les forums j'ai trouvé 2 solutions qui ne me vont pas :
    • Ejecter le 1er utilisateur connecté quand un 2eme se connecte avec le même identifiant. Je veux empêcher le 2ème de se connecter.
    • Enregistrer en base quand un utilisateur se connecte et quand il se déconnecte. Le problème est que rare sont ceux qui se déconnectent proprement, et alors quand il revient la base le voit toujours connecté. Pour pallier à ça, on peut sauver un timestamp à chaque fois qu'il y a une action, et considérer que si la dernière action a plus de 10min, on l'autorise à se reconnecter car la connexion est trop vieille. Mais si l'utilisateur veut se reconnecter moins de 10min après on aura toujours le même problème.

    Est-ce que quelqu'un connait une solution pour empêcher un 2ème utilisateur de se connecter simultanément avec le même compte ?
    (Je précise que c'est un comportement que j'ai déjà vu dans au moins un site, donc c'est possible)

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Le problème c'est que c'est pratiquement infaisable de manière sûre car PHP ne "vit" pas quand il n'y a pas de requête. Donc il n'y a aucun évènement qui arrive quand par exemple la session expire donc aucun moyen donc de savoir parmi les sessions actives quels utilisateurs utilisent actuellement le service et lesquels se sont juste tirée en fermant le navigateur.

    C'est effectivement un comportement possible avec d'autres serveurs d'applications mais pas avec PHP (ou en tout cas pas de manière certaine). Les réponses qui t'on été fournies sont correctes et je n'imagine pas de mécanisme très différent pour faire ce que tu cherches à faire.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut
    Qu'est ce que tu entends par "pas de manière certaine" ?
    Si les cas où ça ne marche pas sont rares, ça peut m'intéresser.

    Et est-ce bien sur qu'il n'y a "aucun moyen de savoir parmi les sessions actives quels utilisateurs utilisent actuellement le service et lesquels se sont juste tirée en fermant le navigateur" ?
    On ne peut pas imaginer une astuce pour ça ?

  4. #4
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Note: je ne suis pas expert en réseau donc si je dis des grosses conneries, merci de me corriger.

    Pour savoir en temps réel si une connexion est active, il faut avoir une socket dédiée. Si je me rappelle bien mes cours de Java, quand on utilise Tomcat par exemple, chaque utilisateur dispose d'un thread dédié (ce qui est au passage extrêmement consommateur), l'avantage c'est qu'on peut à tout moment consulter le pool de threads pour savoir qui est connecté ou en attente et qu'on peut attacher un évènement lors de la fermeture de la socket (par timeout ou par déconnexion manuelle).
    Si l'utilisateur ferme son navigateur, la socket finira par tomber et on pourra proprement marquer l'utilisateur comme déconnecté. Tant que l'utilisateur ne ferme pas son navigateur, le keep-alive tiens la socket debout.

    En PHP c'est impossible, chaque requête HTTP est servie par un thread Apache différent à chaque appel et une fois la requête servie, PHP est arrêté, fin de l'histoire. Apache sait gêrer le keep-alive HTTP pour améliorer les performances mais PHP n'est pas informé de ce qu'il se passe au niveau de la connexion. On ne pourra donc pas attacher d'évènement à la cloture de la session par timeout. Donc à l'instant T on ne sait pas si la session qui était flagguée comme "active" lors de la dernière requête HTTP rencontrée pour cet utilisateur doit être conservée ou jetée. On peut recourir à un timestamp pour déterminer la "fraîcheur" mais c'est hasardeux: on ne peut pas différencier avec certitude un utilisateur qui laisse volontairement un onglet ouvert mais qui ne fait rien d'un utilisateur qui à tout simplement fermé son navigateur.

    Une astuce bien (bien) sale pourrait être d'utiliser un appel Ajax récurent pour tenir à jour l'activité de l'utilisateur

    Par curiosité, quel trésor inestimable nécessite une sécurité de ce genre ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut
    L'idée du timestamp ne me paraît pas mauvaise puisque de toute façon on me demande aussi d'éjecter l'utilisateur s'il n'a rien fait depuis plus de x minutes.
    Mais il faut lui laisser un peu de temps quand même avant de l'éjecter, donc disons que moins de 10min ça va faire trop court. Mais alors s'il ferme son navigateur et veut se reconnecter 3min après, sa session sera toujours active, je vais pas lui dire "ce compte est deja utilisé, veuillez réessayer dans 7 minutes".

    L'astuce de faire des requêtes auto pour tenir la session active, ça risque pas de bouffer beaucoup de ressources? Si je veux régler le problème expliqué juste avant, il faudra que je fasse une requête auto toutes les minutes au moins.

    Pourquoi j'ai ces besoins ? Le site fournit un service qui va devenir payant et on observe sur certains comptes des activités trop rapprochées pour être faites par un seul utilisateur. Il faut donc mettre en place cette sécurité pour limiter les abonnements qui nous passent sous le nez !

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut
    Est-ce que vous avez entendu parler de Comet et du long-polling ?
    J'ai pas bien compris le système, ça peut être utile dans mon cas ?

    Et sinon, est-ce que ce serait possible d'ouvrir une connexion au moment du login, laisser cette connexion ouverte le temps de la visite, et quand l'utilisateur ferme son navigateur et que la connexion est rompue, le php le voit et met à jour ma bdd ?
    Mon site est full-flash mais je peux utiliser aussi le javascript.

  7. #7
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Comme je te l'ai dit, compte tenu de la nature des applications PHP il n'y a pas de solution idéale. Ce ne sera ni fiable à 100% ni faiblement consommateur en ressources.

    Je ne connais pas le principe du long-pooling, je vais y jeter un oeil par curiosité.

    Et sinon, est-ce que ce serait possible d'ouvrir une connexion au moment du login, laisser cette connexion ouverte le temps de la visite, et quand l'utilisateur ferme son navigateur et que la connexion est rompue, le php le voit et met à jour ma bdd ?
    Techniquement, rien n'est impossible mais il faut savoir que toutes les solutions ne sont pas envisageables. Pour faire ce que tu propose, il faut disposer d'un daemon en PHP qui tourne en continu et qui émule le comportement d'un serveur d'application comme Tomcat, Apache jouant le rôle du bridge. C'est passablement compliqué et surtout clairement inadapté au comportement de PHP. Quitte à en arriver là, pourquoi ne pas directement utiliser du Java alors ?

    Personnellement, je pense que dans ton cas, dégager la session existante quand une nouvelle session est ouverte est un compromis acceptable. Tu peux par la suite vérifier les IP et les timestamp de connexion pour détecter les petits malins qui s'échangent des comptes histoire de les bannir. C'est à mon sens la solution la plus envisageable dans ton cas.

    On peut même aller plus loin avec un outil qui permettrai d'envoyer des rapports par mail comprenant les comptes détectés comme frauduleux.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut
    J'ai une autre idée.
    Mon problème c'est que quand l'utilisateur ferme complètement son navigateur, le cookie de session est effacé, et donc s'il essaie de se connecter moins de 15 minutes après (par exemple), la session enregistrée dans la bdd n'est pas assez vieille pour lui permettre de se reconnecter avec ce compte, et il n'a plus le cookie de session qui me permet de le reconnaitre comme étant ce meme utilisateur enregistré dans la bdd.
    Et si pour le session_cookie_lifetime au lieu de mettre 0 (efface à la fermeture du navigateur), je met 15 minutes ? Comme ça quand il rouvre son navigateur il a toujours sa session et il peut utiliser le service.
    Bien sur le problème c'est si c'est pas lui qui rouvre le navigateur 2min après...
    Niveau sécurité/protection de mon service, c'est encore pire ?

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut
    Je suis d'accord que ce serait plus simple que le 2eme connecté éjecte le premier (après tout il avait qu'à pas partager son compte!), mais ce n'est pas négociable.
    Envoyer des requêtes toutes les 30sec pour garder la connexion active, ça ne fait pas l'unanimité non plus

    Donc. Je pars sur le 2ème point du post original, c'est-à-dire que je stock en base quand un utilisateur se connecte et le timestamp à chaque fois qu'il fait quelque chose. Mais en plus, je stock un cookie persistant à chaque fois qu'il fait quelque chose.

    Comme ça s'il ferme son navigateur sans se déconnecter et qu'il le rouvre 2min après, je vois dans la base que ce login a fait quelque chose il y a 2min, et grâce au cookie je vois que ce navigateur avec ce login a fait quelque chose il y a 2min donc je l'autorise à se reconnecter.

    Il y a toujours des limites : si il veut se reconnecter avec un autre navigateur ou qu'il refuse les cookies, il sera traité comme un 2eme utilisateur voulant se connecter sur le compte déjà connecté. Mais ça réduit quand même bien les possibilités de refuser un utilisateur de bonne foi.

    Qu'en pensez-vous ?

  10. #10
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    ça m'a l'air acceptable. Après, pour le cas epsilonesque du client qui change de navigateur, tu peux lui afficher un message d'erreur du style "une autre session est déjà active, veuillez fermer proprement toutes vos connexions puis connectez-vous à nouvau." Avec 2 fallback pour contacter le support si: l'utilisateur se fait toujours jeter (bug) ou s'il est victime d'un vol de comtpe.

    ça ne doit pas t'empêcher de tacker les IP pour détecter les petits malins qui s'échangent les comptes.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut
    est-ce que par hasard tu aurais une idée du pourcentage de visiteurs qui refusent les cookies (pr un site très grand public) ?

    Je lis partout que pour ce qui est des sessions c'est très vilain d'avoir le SID dans l'url, autrement dit avoir session.use_trans_id=1.
    Mais alors comment gérer les navigateurs qui refusent les cookies ?

  12. #12
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je me rappelle plus du pourcentage exact mais l'écrasante majorité des utilisateurs acceptent les cookies. De toute façon tu peux le détecter et renvoyer un message d'erreur si c'est pas le cas.

    Et oui, le SID dans l'URL c'est la porte ouverte aux fixations de session.

  13. #13
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 383
    Points : 10 411
    Points
    10 411
    Par défaut
    Pour le long polling il existe un exemple ici

    Sinon, tu peux évidemment imposer l'utilisation des cookies (et envoyer un message d'erreur si le visiteur les a désactivés). Pour des raisons de sécurité (piratage facile de l'identifiant de session) c'est d'ailleurs très déconseillé de ne pas faire ainsi.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 13
    Dernier message: 24/08/2010, 10h23
  2. Limiter à un connexion sur un même compte
    Par bricechris dans le forum Langage
    Réponses: 11
    Dernier message: 06/02/2010, 15h48
  3. Réponses: 2
    Dernier message: 20/06/2008, 11h48
  4. remplir une colonne entière avec la même valeur
    Par potili2 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 13/11/2007, 12h24
  5. Problème lors d'une deuxième connexion à l'applet
    Par luckyvae dans le forum Applets
    Réponses: 3
    Dernier message: 16/03/2007, 10h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo