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 :

Perte de session


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 186
    Points : 71
    Points
    71
    Par défaut Perte de session
    Bonjour,

    J'ai une application X qui effectue des requêtes Ajax (JSONP) sur une autre application Y (domaine différent) .

    La première requête ajax (JSONP) envoyée par X permet de s'identifier. En retour, Y retourne l'id de la session session_id();

    Ensuite toutes les requêtes envoyé par X (toutes les heures) ont en paramètre l'id de la session.

    Voilà le code coté Y : (j'ai mis en place cette procédure pour éviter les problèmes de cross domain et Internet Explorer)

    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
    <?php
     
    //Fichier appelé par la requête ajax (JSONP)
     
    if(!isset($_GET['session_id'])){
        //On régénère la session
        session_regenerate_id(true);
     
        //On démarre la session
        session_start();
    }
    else{
        session_id($_GET['session_id']);
        session_start();
        if(!isset($_SESSION['APP_Y'])){
            error_log('APP_Y : Session Invalide');
            die();
        }
    }
     
    ?>
    Cependant, de temps en temps j'ai des erreurs log 'APP_Y : Session Invalide',
    mais les fichier de session sont existant sur le serveur.

    Je ne comprend vraiment pas pourquoi, de plus que ces erreurs erreur apparaissent pour n'importe quel navigateur, à n'importe quelle heure.
    Je précise que les requêtes Ajax sont envoyées toutes les heure, donc théoriquement la session ne doit pas être expirée (valeur par défaut d'expiration à 180min).

    Voilà la problématique, si quelqu'un à une idée sur son origine, je suis preneur.

    Merci d'avance pour les réponses.

  2. #2
    Membre confirmé Avatar de guigo
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 612
    Points : 576
    Points
    576
    Par défaut
    Salut,
    effectivement si tu lui passe l'id de la session en cours il n'y a pas de raison que ca ne marche pas. Essaye un phpinfo() pour confimer ton php.ini.
    As tu rebooter ton serveur apache ?
    es tu sur qu'il faille un session_start apres session_id($_GET['session_id']);
    Quand tu fait des echo de ton session_id tu as bien les identifiants=id de session stocke sur ton serveur (meme au moment ou ca plante )?

    Guigo

  3. #3
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Regarde au niveau de la doc pour la fonction session_regenerate_id, l'exemple de code fourni.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //Fichier appelé par la requête ajax (JSONP)
     
    if(!isset($_GET['session_id'])){
        ... etc ...
    }
    else{
        session_id($_GET['session_id']);
    }
    Théoriquement, tu ne peux pas procéder ainsi.
    Il faudrait en 1er démarrer la session, donc session_start(), car le tableau $_SESSION (et ses données) sera dispo qu'après avoir démarrer la session justement, et c'est la même chose pour régénérer un nouvel identifiant, il pourra être changé qu'après démarrage de la session.


    Ensuite, ça dépend de ce que tu veux faire, mais ré-initialiser par exemple l'ID de session avec $_GET['session_id'], c'est théoriquement un trou de sécurité, car quelque part, n'importe qui aura l'occasion de pointer vers ce fichier en rajoutant en paramètre un "session_id", donc de potentiellement récupérer une session d'une autre personne.

    C'est théoriquement plus simple que ça, il suffit de démarrer la session, et théoriquement, si une session existe, l'ID de session sera la bonne.
    Bon, on peu toujours renforcer tout ça, mais c'est un autre débat.


    Théoriquement, toujours, on n'a pas besoin de transmettre l'ID de session, normalement il est déjà transmit dans l'entête, c'est le cookie, il fait partie de la requête HTTP, et c'est justement sa valeur (son ID) qui doit correspondre à un fichier de session coté serveur.
    Si l'un des 2 est manquant, ou erroné, ou encore expirée, lors du session_start(), une nouvelle session sera accordée, et c'est là qu'il y aura perte de session.


    En résumer, ceci seulement devrait fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    session_start();
     
    if (isset($_SESSION['APP_Y'])) {
        // A voir s'il est nécessaire de régénérer l'ID de session
    }
    else {
        // ERREUR
    }
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 186
    Points : 71
    Points
    71
    Par défaut
    Théoriquement, toujours, on n'a pas besoin de transmettre l'ID de session, normalement il est déjà transmit dans l'entête, c'est le cookie, il fait partie de la requête HTTP, et c'est justement sa valeur (son ID) qui doit correspondre à un fichier de session coté serveur.
    Le problème est que ce n'est pas toujours le cas... Internet Explorer par exemple, en Cross Domain, ne passe pas l'identifiant de la session via l'entête HTTP.

    C'est pour ça que j'ai mis en place ce script. Pour pouvoir récupérer la session même si celle-ci n'est pas spécifier par le header de la requête http.

  5. #5
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Le problème est que ce n'est pas toujours le cas... Internet Explorer par exemple, en Cross Domain, ne passe pas l'identifiant de la session via l'entête HTTP.
    Tu est sûr que que tu te trouve dans un cas de cross domaine, qui veut dire qu'on interroge un domaine (ou serveur) B alors que l'origine de la requête HTTP vient d'un domaine A ?
    Est ce vraiment le cas ? (j'ai plutôt tendance à dire que non).

    Si c'est le cas, et bien la perte de session devrait être systématique quelque soit le navigateur, pas seulement d'Internet Explorer, car théoriquement, quand on intérrogera pour la 1ère fois le domaine B (1ère requête HTTP), la session n'aura pas encore été créé, donc le cookie envoyé (du domaine A) ne correspondra jamais à une session du domaine B.
    Une nouvelle session sera automatiquement accordée, du coup, une incohérence existera entre les 2 domaines au niveau des sessions.
    Enfin, c'est ainsi que je le perçois, je peux me tromper.


    Ce ne serait pas dû au format JSON plutôt ?
    As tu essayé de rajouter la valeur du cookie de session dans le JSON par exemple ?
    J'ai jamais eu l'occasion de faire des essai en JSON malheureusement (un de ces 4 faudrait que j'essaye d'ailleurs), je ne pourrais en dire plus.
    As tu fais des essai sur IE justement mais pas au format JSON, un simple fichier php qui retournerai un echo, et regarder si la session est conservée, est la même?

    En faite ici, la question que je me pose, c'est est ce qu'il ne serait pas nécessaire de définir le type/format de fichier qu'on a affaire, soit du JSON dans l'entête, faire un header('... je ne sais pas trop quoi ... /json') avant de démarrer la session.
    Fausse piste peut être, mais c'est on jamais.


    Ou alors, il faudrait peut être voir comment le cookie est créé, à quel domaine domaine il appartient, son chemin plus exactement, etc ...
    Tu peux le vérifier du coté du ou des navigateurs que tu utilise.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 186
    Points : 71
    Points
    71
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tu est sûr que que tu te trouve dans un cas de cross domaine, qui veut dire qu'on interroge un domaine (ou serveur) B alors que l'origine de la requête HTTP vient d'un domaine A ?
    Oui les requêtes sont effectuées à travers deux domaines différents...

    Je re-explique le problème, la première requête (App X domaine A) sert à instancier la session sur l'app Y (domaine B).

    Ensuite les requêtes effectuée depuis l'app X (toutes les heures), sont censées utiliser la session instanciée lors de la première requête.

    Le problème est qu'IE ne passe passe pas l'identifiant de la session naturellement, il faut donc le préciser.

  7. #7
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Je suis désolé, c'est de ma faute, c'est cette fichue manie de lire en diagonale.

    Ca a bien été expliqué dès au début


    Du coup, envoyer l'ID de session serait finalement nécessaire.
    En tout cas, interroger sur une même page Web un domaine différent, c'est quand même particulier.


    Mise à par ça, le reste est toujours valable, c'est à dire qu'il faut démarrer la session avant de régénérer l'ID.

    Mais à mon avis, il faudrait transmettre aussi la variable de session "APP_Y", car lors de la toute 1ère requête HTTP qu'il y aura sur le serveur B, cette donnée est théoriquement inconnue, elle est connue que du serveur A. (tout comme l'ID de session d'ailleurs).
    C'est peut être pour ça que le condition sur ce APP_Y provoque l'erreur.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 186
    Points : 71
    Points
    71
    Par défaut
    La session de App Y est justement renvoyé a App X lors de la connexion et à chaque fois que que App X envoie une requête elle passe la variable de session à App Y ($_GET['session_id'])

    Un petit schéma :


  9. #9
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Un petit schéma :
    Il n'y a malheureusement pas de schéma

    La session de App Y est justement renvoyé a App X lors de la connexion et à chaque fois que que App X envoie une requête elle passe la variable de session à App Y
    Ok, mais lors de la toute 1ère requête HTTP qu'enverra App X du domaine A vers domaine B, la variable de session "App_Y" sera inconnue du domaine B, et même que tant quelle ne sera pas créé.
    Cette condition devrait retourner VRAI dans ce cas là, donc erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (!isset($_SESSION['APP_Y'])) {
        error_log('APP_Y : Session Invalide');
        die();
    }
    A mon sens, et au mieux, $_SESSION['APP_Y'] n'est connue que du coté du domaine B, pas du domaine A.
    Les données en session du domaine A et B ne communiquent pas entre elles, donc si d'un coté ou de l'autre on a besoin de telle ou telle données, faut les transmettre, pas seulement l'ID de session.

    Donc que App Y renvoie certaines infos, d'accord, mais il faut voir quand même ce que reçoit App Y, s'il manque pas certaines données.

    En tout cas, transmettre l'ID de session ne signifie pas que les données contenues dans la session soient transmises.
    Enfin, j'en doute.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 186
    Points : 71
    Points
    71
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    A mon sens, et au mieux, $_SESSION['APP_Y'] n'est connue que du coté du domaine B, pas du domaine A.
    Les données en session du domaine A et B ne communiquent pas entre elles, donc si d'un coté ou de l'autre on a besoin de telle ou telle données, faut les transmettre, pas seulement l'ID de session.
     
    Donc que App Y renvoie certaines infos, d'accord, mais il faut voir quand même ce que reçoit App Y, s'il manque pas certaines données.
     
    En tout cas, transmettre l'ID de session ne signifie pas que les données contenues dans la session soient transmises.
    Enfin, j'en doute.
    Je ne voie pas le rapport avec mon problème...

    Ce qu'il se passe c'est que lors de la première requête, App Y crée une session, il renvoie le session_id de cette session à App X.

    Ensuite lorsque App x Fait des requêtes vers App Y, il fournit l'identifiant de la session pour identifier la session à utiliser.

    Cependant, certaines fois l'identifiant de session envoyer à App X ne correspond à aucune session sur App Y.

  11. #11
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Faire des requêtes au format JSON comme je l'avais dit, j'ai jamais essayé, mais JSONP, en est encore autre chose.

    Je découvre tout juste.

    Une recherche très rapide m'a amené vers un article de Cyril Durand intitulé JSONP : comment faire des requete JSON cross-domain
    Je tente de résumer ce que j'ai compris.
    Cette technique permet normalement de résoudre le problème de Cross Domaine qu'il existe entre le serveur A et le serveur B.
    Aussi, la théorie veut donc qu'il n'est plus de problème lié au navigateur, y compris IE.
    La 1ère étape consiste à inclure un code JS dans la page HTML venant du domaine B.
    Puis ce code JS, de l'Ajax, lorsqu'il sera exécuté (peu importe la technique) fera qu'une requête HTTP sera envoyée du domaine B vers le domaine B du faite que ce trouve sur ce domaine B, l'astuce serait justement là.


    J'ai donc dit à plusieurs reprises des bêtises.
    La question que je me pose maintenant, c'est quand est il des cookies ?
    La théorie veut qu'aucun cookie ne soit envoyé vu qu'au niveau du navigateur, la page Web appartient au domaine A.
    En finalité, le problème reste entier concernant les couples cookie/session, pour en faite conserver une persistance au niveau des données lors des requêtes HTTP de l'Ajax.
    Là, je ne saurais quoi faire.
    Est ce qu'il vaut mieux envoyer en paramètre le session_id comme actuellement dans l'URL pour à chaque reprendre cet ID ?
    Ou est ce qu'il ne serait pas possible de créer un 2ème cookie pour le domaine B dans le navigateur dans l'espoir qu'il sera envoyé dans l'entête HTTP ?


    Mais une question me vient à l'esprit.
    Pourquoi faudrait il créer une session sur le domaine B, est-ce vraiment utile ?
    Ne faudrait il pas juste se contenter de transmettre en paramètres les données dont le serveur B auraient besoin ?

    Aussi, lorsqu'il y a ces requêtes HTTP entre domaine B et domaine B (JSONP), et bien le cookie se trouvant coté client n'appartenant pas au domaine B mais au domaine A, celui ci ne sera théoriquement jamais mis à jours, en tout cas, pas tant que le page ne sera pas rechargée ou actualisée.



    Malgré tout ceci, il reste néanmoins un aspect donc je n'explique pas.
    Si je reprend le code tel qu'il est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if(!isset($_GET['session_id'])){
     ... etc ...
    }
    else{
        ... etc ...
    }
    La logique veut qu'on entre tout le temps dans le else { ... } étant donné que le "session_id" est systématiquement envoyé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        session_id($_GET['session_id']);
        session_start();
        if(!isset($_SESSION['APP_Y'])){
            error_log('APP_Y : Session Invalide');
            die();
        }
    C'est donc ce code qui sera exécuté à chaque fois.
    Si je prend son déroulement, en 1er on (re)défini l'ID de session.
    En 2ème on démarre la session. Jusque là tout va bien.
    Mais à ce stade, et lors de la 1ère requête HTTP, le tableau $_SESSION est vide vu qu'il y a aucun code se chargeant de créer une quelconque variable de session.
    En 3ème, et bien, toujours lors de la 1ère requête HTTP, la condition sera VRAI, soit que "APP_Y" n'existe pas vu que le $_SESSION ne contient rien, donc erreur et die(), soit le script s'arrête là.
    Si je poursuis, c'est à dire lors d'une 2ème requête HTTP, ce même code sera exécuté, et comme "APP_Y" n'a toujours pas été créé, et bien ça aboutira à la même chose, et ainsi de suite.


    Enfin, voilà comment je perçois les choses, et je n'arrive pas à comprendre pourquoi ce code fonctionnerait de temps à autre, ou échouerait de temps à autre.
    Pour ma part il devrait échouer à chaque fois, à chaque requête.
    Il doit subsister encore quelque chose dont j'en ai pas connaissance malheureusement, ou le code est différent, peu importe.



    Bon, comme tu peux voir je n'est pas de solutions, je t'expose seulement mon raisonnement, peu importe qu'il soit juste ou pas, je me dis que dans tout ça il y a peut être un détail qui te permettras de débloquer la situation.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 186
    Points : 71
    Points
    71
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    La logique veut qu'on entre tout le temps dans le else { ... } étant donné que le "session_id" est systématiquement envoyé.
    Non le session id n'est pas envoyé lors de la première requête d'identification.

  13. #13
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Non le session id n'est pas envoyé lors de la première requête d'identification.
    D'accord.
    Mais pour quelle raison ?

    Je part sur cet aspect la donc :
    Mais toujours lors de cette 1ère requête, ce qui fait qu'on entre finalement dans la 1er condition, est ce que la variable de session "APP_Y" est créé ?
    D'ailleurs, je ne vois pas de raison de faire un session_regenerate_id(true) vu qu'aucune session n'existait encore.
    Qu'est ce que tu en pense ?


    Si je poursuit, on va se retrouver avec un ID de session unique, celui que le serveur B aura créé.
    Les IDs de sessions sont normalement à ce stade différents entre le serveur A et le serveur B.

    Et bien que fait tu après ?
    Tu renvoie en réponse l'ID de session obtenu lors de cette 1er requête vers le navigateur, qui après lors des autres requêtes transmettre ce même ID, c'est ça ?
    Ou est ce que tu transmet l'ID de session du serveur A ?
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

Discussions similaires

  1. [JSP][session] perte de session et sendRedirect
    Par blaz dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 30/03/2007, 09h32
  2. Perte de Session d'une page à l'autre
    Par Flam dans le forum Langage
    Réponses: 3
    Dernier message: 15/03/2006, 14h34
  3. [Struts]Redirection globale en cas de perte de session
    Par Mercenary Developer dans le forum Struts 1
    Réponses: 10
    Dernier message: 03/02/2006, 14h40
  4. [navigateur]Problême de pertes de sessions sous IE (.js)
    Par Invité4 dans le forum Général JavaScript
    Réponses: 26
    Dernier message: 21/11/2005, 17h53
  5. [VB.NET] Perte de session entre 2 projets
    Par TekP@f dans le forum ASP.NET
    Réponses: 3
    Dernier message: 02/05/2005, 09h12

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