Partage
  • Partager sur Facebook
  • Partager sur Twitter

Partage de session et cookie qui expire trop tôt

Sujet résolu
    27 décembre 2017 à 10:33:55

    Bonjour !

    Je viens vers vous aujourd'hui puisque je suis confrontée à un problème embêtant.

    Contexte :

    • Je dispose de 8 applications pour mon entreprise
    • Elles requièrent toutes une identification via Active Directory
    • Si une personne s'authentifie sur l'app1, sa session doit être partagée sur les autres app -> elle ne doit pas avoir à retaper le mot de passe et le login.

    Actuellement, j'ai essayé de multiples choses qui ont toutes été peu concluantes :

    • Configuration du cookie directement dans le php.ini (solution retirée)
    • Configuration en PHP avant le session_start() (solution courante)
    • Les deux, sait-on jamais !
    • Aucun, et bien sûr il n'y a pas de partage
    • Certainement d'autres trucs un peu marabout dont je ne me souviens plus

    Je dispose également d'une session, bien sûr, appelée "application_pilot".

    Le cookie est configuré lorsque l'utilisateur se connecte : ce cookie est nomméusername_chaineAleatoire (par ex.: nileeda_0d0a9abbe96986ee0c32b2492ea77e64f249ef09)

    Mon problème : Bien que le partage de session fonctionne bien, les cookies semblent expirer avant leurs dates d'expiration. Si je laisse le cookie expirer totalement, l'app se comporte de la bonne manière : il redemande une authentification. Mais si j'actualise la page après une période d'inactivité inférieure au délai de vie du cookie (ex.: 1h, le temps de la pause dej), j'obtiens une page m'indiquant que je n'accepte pas les cookies.

    Je cherche à résoudre ce problème qui est assez embêtant : nous devons supprimer les cookies concernés et se reconnecter. Solution déjà embêtante pour nous, complètement invivable pour les utilisateurs.

    Configuration :

    • Serveur Apache2
    • PHP 5.6.30 (fpm)
    • Framework "maison", créé par un ancien collaborateur
    • Le bug est présent sur tous les navigateurs (Firefox, Chrome, IE > 9 & Edge testés)

    Code concerné :
    Ouverture de session :

    /*Démarrage de Session*/
    session_name('application_pilot');
    //ini_set('session.cookie_domain', substr($_SERVER['SERVER_NAME'], strpos($_SERVER['SERVER_NAME'], "."), 100));
    ini_set('max_execution_time', 300);
    session_set_cookie_params('36000', '/', '.pilot.corp');
    session_start();
    
    /*Regénère le session_id pour augmenter la sécurité*/
    session_regenerate_id();


    Déclaration d'une session à l'authentification :

    if(null !== $password)
            {
                //Récupère les informations LDAP et crée l'objet UserLDAP
                $user = self::requestUser($username, $password);
    
                //Si les informations de l'utilisateur ont pu être récupérée
                if(false !== $user)
                {
                    //Creation du clef de sécurité
                    $key = self::createVerifKey($username);
    
                    // securisation des sessions
                    $cryptedKey = $username."_".$key;
    
                    //Création de la session utilisateur
                    $_SESSION['username'] = $cryptedKey;
    
                    //Intégration de l'objet UserLDAP au format serialized
                    $_SESSION['user'] = serialize($user);
    
    
                    //Création de la session pour le stockage de variables liées à l'application si non existante
                    if(false === isset($_SESSION[self::$application]))
                        $_SESSION[self::$application] = array();
    
                    //Création du cookie
                    setcookie(self::$application, $cryptedKey, time()+36000, '/', '.pilot.corp');
    
                }
            }

    Il y a des choses que je ne pourrais pas expliquer totalement dans ces morceaux de code : je ne suis pas la créatrice du framework, et bien que je travaille avec depuis 1 an, je ne le connais pas encore dans les détails !

    J'ai écumé Google, évidemment, mais je n'ai pas trouvé quelque chose de concluant pour résoudre ce souci. Peut-être n'ai-je pas/plus les bons mots clés ?

    Merci d'avance pour votre aide éventuelle ! Toute piste est bonne à prendre ^^

    Bonne journée,

    • Partager sur Facebook
    • Partager sur Twitter
      27 décembre 2017 à 11:05:46

      Bonjour,

      Je pense avoir a peu près saisi le fonctionnement global de votre "astuce" et j'ai rencontré moi-même un problème similaire lorsque j'ai développé un système de login qui permet de déposer dans le navigateur un jeton spécifique sous la forme d'un cookie valide 30 jours (essentiellement conçu pour l'usage sur périphérique nomade que les utilisateurs verrouillent par ailleurs).

      Le problème que j'ai rencontré intervenait quand la session ouverte grâce à l'identification par saisie login/mot de passe arrivait à son terme (par exemple en raison de l'atteinte de la durée maximum d'inactivité tolérée par la directive de configuration PHP session.gc_maxlifetime) tout en ayant correctement créé le cookie correspondant au jeton, ce cookie étant donc valide. Mon test de sécurité exécuté à chaque fois qu'un utilisateur fait quelque chose nécessitant d'être connecté échouait, la session PHP ayant pris fin, la variable témoignant de la bonne connexion n'existant dès lors plus.

      Je ne sais pas comment sont gérées les sessions dans votre système mais il est très probable qu'il existe deux cookies... Le vôtre, et celui déposé par PHP pour mémoriser la session, généralement appelé PHPSESSID. Si celui-ci arrive à échéance et que votre système n'est pas capable de faire en sorte que le relais soit pris par votre propre cookie, en le vérifiant, puis en déclenchant automatiquement une nouvelle session PHP "comme si" l'utilisateur venait d'utiliser le formulaire de connexion... Alors cela déconne. Si les sessions PHP sont gérées autrement que via un Cookie (par exemple via une base de données), ce type de "problème" peut alors être totalement "invisible" pour vous.

      Le "bug" constaté provient certainement d'une différence de timming entre durée de validité de votre "cookie maison" et durée de validité du cookie "PHP" (ou de la session stockée ailleurs que via un cookie).

      • Option 1 : essayer de modifier la durée de validité du cookie PHP http://php.net/manual/fr/session.configuration.php#ini.session.gc-maxlifetime qui est par défaut de 1440 secondes soit 24 minutes.
      • Option 2 : prévoir un mécanisme, entre le rejet pour cause de non connexion et le renvoi sur le formulaire de connexion, qui va regarder su un cookie "maison" est présent, le vérifier, et restaurer une session valide avant de recharger la page demandée... cette fois sans problème en toute logique.

      Pour ce qui me concerne j'ai choisi pour mon projet l'option 2. Pour vous donner une idée, mon script de sécurité ressemble à :

      • Utilisateur connecté ? Oui -> Affichage effectué
      • Non, utilisateur avec un Cookie ? Non -> Page de login
      • Oui, est-ce que ce Cookie est toujours considéré comme valide ? Oui -> Restauration Connexion / Session -> Affichage demandé
        Cette vérification est chez moi rendue nécessaire par la possibilité qu'un utilisateur a d'invalider un cookie déposé sur un appareil
        Depuis un autre appareil (une sorte d'autorisation révocable) ce qui doit évidemment se faire sans toucher à l'appareil concerné
      • Non -> Message d'erreur + Page de login

      Donc quand on en arrive à Oui, Cookie valide, Affichage demandé, la même sécurité est rappelée mais s'arrête désormais dès le début : utilisateur connecté, oui, affichage effectué.

      J'espère que ça pourra donner des idées pour la suite... ;)

      Edit : il faut voir aussi du côté de session.cookie_lifetime pour la durée de validité du Cookie de session PHP (et non de la session elle-même) ce qui sont deux choses différentes, l'une étant côté serveur, et l'autre côté client. Par défaut le cookie est valable jusqu'à la fermeture du navigateur.

      -
      Edité par Nicolas B 27 décembre 2017 à 12:27:45

      • Partager sur Facebook
      • Partager sur Twitter
      Nicolas - Développeur PHP qui bricole pas mal, utilisant Bootstrap, Materialize, MySQL et quelques astuces piochées par ci par là. Codeigniter a changé ma vie de codeur :D
        28 décembre 2017 à 14:09:36

        Bonjour,

        J'ai testé votre première option en priorité et mon souci semble réglé ! J'ai pu partir en pause déjeuner sans avoir à effacer mes cookies à mon retour -> c'est un test plutôt concluant :)

        Si toutefois le problème se reproduit, je m'attaquerais à la seconde option que vous proposez qui m'a l'air tout à fait viable également ^^

        J'avais en effet configuré le session.cookie_lifetime lors de la création du cookie (un des paramètres de la fonction session_set_cookie_params) mais je ne savais pas que session.gc-maxlifetime était prioritaire sur le reste. Je l'avais déjà croisé sans réellement m'y attarder, pensant que seuls les cookies étaient en cause alors que ce n'était apparemment pas le cas !

        Un grand merci à vous,

        Joyeuses fêtes de fin d'année !

        • Partager sur Facebook
        • Partager sur Twitter
          28 décembre 2017 à 14:50:29

          C'est un plaisir que de vous épargner... après le déjeuner... une indigestion répétée due à l'abus de cookies... périmés ! :D
          • Partager sur Facebook
          • Partager sur Twitter
          Nicolas - Développeur PHP qui bricole pas mal, utilisant Bootstrap, Materialize, MySQL et quelques astuces piochées par ci par là. Codeigniter a changé ma vie de codeur :D

          Partage de session et cookie qui expire trop tôt

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown