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

PHP & Base de données Discussion :

problème avec TIMESTAMP [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Gard (Languedoc Roussillon)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 40
    Points : 39
    Points
    39
    Par défaut problème avec TIMESTAMP
    Bonsoir
    J'ai un gros soucis !

    Je suis en train de me torturer les neurones avec un projet de site qui devra gérer un espace membre.
    Je vous passe les détails et je vais essayer d'être concis.

    Quand un utilisateur tente de se connecter et que le couple user/pass est vérifié, une fonction assigne à $_SESSION['idUser'] l'id de l'utilisateur. Comme ça il me suffit de vérifier que $_SESSION['idUser'] existe pour savoir si un utilisateur est connecté et a passé le "barrage".

    Mais pour plus de sécurité j'ai envi de m'appuyer sur une base de données. J'ai créé une table "Sessions" (je vous montre la requête de création (((générée par phpMyAdmin))) ça ira plus vite que de longues explications...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE TABLE `test`.`Sessions` (
    `id` VARCHAR( 26 ) NOT NULL ,
    `id_user` SMALLINT( 3 ) UNSIGNED NOT NULL ,
    `expire` TIMESTAMP NOT NULL
    ) ENGINE = MYISAM ;
    Ainsi, ma fonction n'assigne pas seulement une valeur à $_SESSION['idUser'] mais remplit aussi la table Sessions avec l'id de la session en cours, l'id de l'utilisateur et une date d'expiration.
    Le but du jeu est que mon application vérifie que la variable de session existe ET que celle-ci corresponde à une entrée dans la table Session ET que la session soit encore valide.

    Voici un peu de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    // Fonction qui "crée" la session une fois que l'utilisateur a correctement saisi son login et pass
    function creerSession($idUser, $pseudo) {
     
    	$_SESSION['idUser'] = $idUser;
    	$_SESSION['pseudo'] = $pseudo;
     
    	session_regenerate_id();
    	$idSession = session_id();
     
    	// BDD_HOST etc. sont des constantes correctement définies
    	$pdo = new PDO("mysql:host=" . BDD_HOST . ";dbname=" . BDD_BASE, BDD_USER, BDD_PASS);
     
    	$idSql = $pdo->quote($idSession);
    	$idUserSql = $pdo->quote($idUser);
     
    	// Il semble y avoir un problème ici. Avec CURRENT_TIMESTAMP + 1800 ??? C'est le +1800 ???
    	$req = "INSERT INTO MPR_Sessions (id, id_user, expire) VALUES ($idSql, $idUserSql, CURRENT_TIMESTAMP + 1800)";
     
    	$pdo->exec($req);
     
    }
    Ouf, si vous avez eu le courage de lire mes pavés, on en vient au problème :

    Pendant quelques instants, les tests de session dans mon application marchaient à merveille ! Puis à force de tests, je me suis rendu compte que ça ne marchait plus. Puis de nouveau opérationnel...
    Après m'être arraché beaucoup de cheveux, j'ai découvert quelque chose de louche !
    En surveillant la table Session, j'ai remarqué que certaines lignes étaient correctes (le champ ‘expire‘ contient le timestamp du login + 30 minutes) mais d'autres non Là le champ ‘expire‘ vaut tout simplement 0 ! (phpMyAdmin m'affiche 0000-00-00 00:00:00).

    Si j'étais toujours un seul cas je comprendrais, mais là...
    pour info je suis en local, avec un serveur apache 2.2.14 (intégré à MacOSX), PHP 5.3.1 et MySql 5.0.5.
    Est-ce mes serveurs locaux qui partent en live ou est-ce mon code qui n'est pas top ?


    Vous m'avez lu jusqu'ici, je vous remercie beaucoup
    Et encore plus si vous avez des réponses ou remarques

  2. #2
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Bonsoir, il suffit simplement que tu fasses ceci :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $req = "INSERT INTO MPR_Sessions (id, id_user, expire) VALUES ($idSql, $idUserSql, ADDDATE(CURRENT_TIMESTAMP(), INTERVAL 1800 SECOND))";

  3. #3
    Membre confirmé
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Points : 597
    Points
    597
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    J'ai plein de choses à te dire^^
    La première est qu'il n'est pas judicieux pour un contrôle d'accès d'avoir choisi un champ expire d'une part et d'autre part de le choisir en timestamp.

    Pourquoi?

    Pour commencer, ta base de donnée n'est pas dynamique au sens php du terme. Ce n'est pas à ta base de données de donner l'info si la connexion en cours est expirée mais php. Si ca n'est toujours pas clair, je te donne un exemple. Si tu choisi un temps d'expiration de 5min, et que l'utilisation de la session de l'utilisateur fait que la base de données est intérogée 10min plus tard, il y aura 5min d'utilisation non autorisé non controlé.
    La meilleure méthode est de loguer par un timestamp avec comme valeur par défaut current_timestamp (pas besoin de l'inclure dans l'insert donc). Ensuite en paramétrage de ton application, tu règles le temps en secondes de ton timeout, et c'est php qui vérifie à chaque demande de page si il y a timeout ou pas. Si il y a timeout, on log la fin de session via un champ supplémentaire en datetime avec un now() dans la requête update.
    De cette manière tu as un véritable contrôle de timeout réactif à la seconde près et tu sais au niveau de tes logs que l'user x c'est connecté tel jour à telle heure et c'est déconnecté à telle heure du même jour, ce qui te permet une véritable vérification de sécurité au niveau des connexions.

  4. #4
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Dans l'absolu, tu as raison sauf qu'il veut gérer apparemment un espace membre et que certaines fonctionnalités qu'il veut peut être mettre au point ne seront pas possibles si sa dernière action est stockée en session uniquement.

    Je prends l'exemple d'un forum : comment fais tu si tu stockes uniquement en session pour voir ma dernière activité sur ce forum ? Tu es obligé de scanner la session d'un autre utilisateur, ce qui tu en conviendras n'est pas possible.

    phpbb ainsi que d'autres, possèdent tous en base une table style "connected_users" justement pour palier ce genre de problèmes.

    Ceci dit, peut être qu'avec les sessions, ce qu'il veut faire est envisageable

  5. #5
    Membre confirmé
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Points : 597
    Points
    597
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Dans mon cas de figure les connected users sont ceux qui ont leur champ logout (en datetime) = null.
    Et puis tu fais comment pour gérer le timeout si tu ne peux pas le rafraichir à chaque demande de page en base de données? T'es bien obligé soit de mettre à jour ton timestamp login (mais tu écrases l'info de première connexion) soit tu mets à jour un champ 'lastping' en datetime qui sert à reset ton timer.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    40
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Gard (Languedoc Roussillon)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 40
    Points : 39
    Points
    39
    Par défaut
    Bonjour!
    Merci pour vos réponses, je les ai lues et ça m'a aidé à faire le point la gestion des connexions.
    Merci beaucoup pour le ADDDATE dans la requête, j'avais fait ça un peu à la volée

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

Discussions similaires

  1. Problème avec fabrication de timestamp
    Par jaaf64 dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 31/10/2012, 17h29
  2. Problème avec TIMESTAMP
    Par Tchupacabra dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 20/06/2007, 11h41
  3. problème avec TIMESTAMP DEFAULT NULL
    Par Tchupacabra dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 06/06/2007, 16h18
  4. problème avec le type timestamp
    Par aline dans le forum Oracle
    Réponses: 6
    Dernier message: 21/02/2005, 10h05
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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