web-dev-qa-db-fra.com

PHP Sessions à travers les sous-domaines

J'essaye de mettre en place ce qui suit:

auth.domain.com
sub1.domain.com
sub2.domain.com

où, si l'utilisateur visite sub1.domain.com ou sub2.domain.com et qu'il n'est pas connecté, il est transféré sur auth.domain.com et peut se connecter. sub1.domain.com et sub2.domain.com sont deux applications distinctes mais utilisent les mêmes informations d'identification.

J'ai essayé de définir ce qui suit dans mon php.ini:

session.cookie_domain = ".domain.com"

mais cela ne semble pas transmettre l'information d'un domaine à un autre.

[Modifier]

J'ai essayé ce qui suit:

sub1.domain.com/test.php

session_set_cookie_params(0, '/', '.domain.com');
session_start();
print session_id() . "<br>";
$_SESSION['Regsitered'] = 1;
echo '<a href="http://auth.domain.com/test.php">Change Sites</a>'

auth.domain.com/test.php

session_set_cookie_params(0, '/', '.domain.com');
session_start();
print session_id() . "<br>";
$_SESSION['Checked'] = 1;
print_r($_SESSION);

Les identifiants de session sont exactement les mêmes, mais lorsque je vide la variable $ _SESSION, celle-ci n'affiche pas les deux clés, mais peu importe la clé que j'ai définie sous chaque domaine.

[Modifier 2]  

J'ai mis à jour [Modifier]

87
dragonmantank

Je ne sais pas si le problème persiste, mais j’ai rencontré le même problème et je l’ai résolu en définissant un nom de session avant d’appeler session_set_cookie_params ():

$some_name = session_name("some_name");
session_set_cookie_params(0, '/', '.some_domain.com');
session_start();

Je n'ai rien changé dans mon php.ini mais maintenant tout fonctionne bien.

127
jeroen

Une chose qui peut mystérieusement empêcher la lecture des données de session sur un sous-domaine, même si les cookies sont correctement configurés sur .domain.com est le correctif Suhosin PHP. Tout peut être configuré correctement, conformément aux exemples de la question, et cela peut tout simplement ne pas fonctionner.

Désactivez les paramètres de session Suhosin suivants et vous serez de retour dans les affaires:

suhosin.session.cryptua = Off 
suhosin.session.cryptdocroot = Off
24
drewm

Essayez d'utiliser:

session.cookie_domain = "domain.com"

Au lieu de:

session.cookie_domain = ".domain.com"

Notez la période manquante.

Soyez prudent en utilisant ceci, car il n'est pas supporté par tous les navigateurs.

5
George Claghorn

Avait ce problème exact - je voulais que les valeurs de session créées sur x.example.local soient disponibles sur example.local et vice-versa.

Toutes les solutions que j'ai trouvées disaient changer le domaine de la session en utilisant php_value session.cookie_domain .example.local dans .htaccess (ou via php.ini ou via ini_set). 

Le problème était que je définissais le session.cookie_domain pour tous les sous-domaines (jusqu'à présent, ok), mais aussi pour le domaine principal. Définir le session.cookie_domain sur le domaine principal est apparemment non-non.

Fondamentalement, cela a fonctionné pour moi: 

  • définit le session.cookie_domain pour ALL SUBDOMAINS.
  • ne le configure pas pour le DOMAIN principal  

Oh oui, veuillez vous assurer que le domaine a un TLD (dans mon cas .local). Le protocole HTTP n'autorise pas le stockage des cookies/sessions sur un domaine sans .tld (c'est-à-dire que localhost ne fonctionnera pas mais que stuff.localhost le fera).

EDIT: Assurez-vous également de toujours effacer les cookies de votre navigateur lors du test/débogage de sessions sur plusieurs sous-domaines. Si vous ne le faites pas, votre navigateur enverra toujours l'ancien cookie de session qui n'a probablement pas encore défini le cookie_domain correct. Le serveur relancera l'ancienne session et vous obtiendrez donc des résultats faux négatifs. (dans de nombreux articles, il est mentionné d'utiliser session_name ('stuff') pour le même effet)

4
Valentin Florea

Je l'ai résolu comme ça

ini_set('session.cookie_domain', '.testdomain.dev');
session_start();

Parce que je travaillais sur localhost 

ini_set('session.cookie_domain', '.localhost');

ne fonctionnait pas , il voit .localhost comme le niveau supérieur au lieu de .com/.local/... (je soupçonne)

J'ai aussi utilisé .dev parce que travailler sur OS X ne semble pas résoudre le .com en tant que premier dans HOSTS

3
xtds

J'ai confirmé. Joreon la réponse de/est correcte. Je ne peux pas commenter parce que ma réputation n'est pas suffisante, alors je poste mon commentaire ici.

Définissez la constante dans un fichier de configuration. Si vous voulez le changer, pas besoin de modifier des fichiers entiers.

define('ROOT_DOMAIN',   'mysite.com');
define('PHP_SESSION_NAME', 'MYSITE'); 

Le nom de session ne peut pas être composé uniquement de chiffres, au moins une lettre doit être présente. Sinon, un nouvel identifiant de session est généré à chaque fois.

Utilisez le code suivant pour commencer à utiliser session

session_name(PHP_SESSION_NAME);
session_set_cookie_params(0, '/', '.' . ROOT_DOMAIN);
session_start();

J'utilise cette fonction:

function load_session() {
    if (session_status() == PHP_SESSION_NONE) {
        session_name(PHP_SESSION_NAME);
        session_set_cookie_params(0, '/', '.' . ROOT_DOMAIN);
        session_start();
    }
    else {
        if (session_name() != PHP_SESSION_NAME) {
            session_destroy();
            session_name(PHP_SESSION_NAME);
            session_set_cookie_params(0, '/', '.' . ROOT_DOMAIN);
            session_start();
        }
    }
}
load_session(); // put it in anywhere you want to use session
2
Terry Lin

Utilisez-le sur chaque domaine/sous-domaine:

session_name('name');
ini_set('session.cookie_domain', '.example.com');
ini_set('session.save_path', '/var/lib/php/session');
session_start();

Le chemin pour session.save_path peut être différent pour votre cas, mais il devrait s'agir du même sur chaque domaine/sous-domaine Ce n'est pas toujours vrai par défaut.

2
Nobody Tells

Utilisez ceci, cela fonctionne: 

ini_set('session.cookie_domain', 
    substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
1
Ivan

Utilisation combinée des sessions de cookie du domaine de sous-domaine et du domaine racine

Ressource: http://php.net//manual/tr/function.session-set-cookie-params.php

J'ai testé des œuvres

sub.exampledomain.com/sessionadd.php?id=123

exampledomain.com/sessionview.php // 123

-- Codes

<?php 
$currentCookieParams = session_get_cookie_params(); 

$rootDomain = '.example.com'; 

session_set_cookie_params( 
    $currentCookieParams["lifetime"], 
    $currentCookieParams["path"], 
    $rootDomain, 
    $currentCookieParams["secure"], 
    $currentCookieParams["httponly"] 
); 

session_name('mysessionname'); 
session_start(); 

setcookie($cookieName, $cookieValue, time() + 3600, '/', $rootDomain); 
?>
1
Limitless isa

J'ai lu toutes les réponses ci-dessus, je pense que ma réponse est utile pour les personnes recherchant cela sur Google.

* Assurez-vous que les navigateurs envoient le cookie de session aux serveurs (du domaine et des sous-domaines), définissez le domaine de cookie de session sur ".example.com".

* Assurez-vous que php trouve la bonne "cible" pour restaurer la session var - Si le domaine et les sous-domaines pointent vers la même machine (peut-être différents hôtes virtuels), assurez-vous que "session_save_path" est identique testé) - Si le domaine et les sous-domaines pointent vers différentes machines, le stockage commun (comme la base de données) est préférable pour la sauvegarde et la restauration des données de session (je n'ai pas encore testé). Utilisez "session_set_save_handler" pour le faire.

0
user953985

J'ai l'impression que vous ne voulez pas quelque chose comme OpenID, comme le suggère Joel, mais que vous voulez avoir accès aux données de session sur plusieurs domaines.

La seule possibilité que je puisse envisager comme solution à ce problème consiste à stocker les données de la session dans une base de données et à les extraire de cette base de données.

0
Thomas

Je sais que c'est vieux, mais cela fonctionne bien pour moi avec plusieurs domaines et sous-domaines sur la même boîte.

<?php
define('site_domain','domain.com');
session_set_save_handler('_open',
                         '_close',
                         '_read',
                         '_write',
                         '_destroy',
                         '_clean');

function _open(){

    global $_sess_db;

$db_user = 'user';
$db_pass = 'pass';
$db_Host = 'localhost';

if ($_sess_db = mysql_connect($db_Host, $db_user, $db_pass)){

    return mysql_select_db('database', $_sess_db);

}

return false;

}

function _close(){

    global $_sess_db;
    return mysql_close($_sess_db);

}

function _read($id){

    global $_sess_db;
    $id = mysql_real_escape_string($id);
    $domain = mysql_real_escape_string(site_domain);
    $agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));

    $sql = "SELECT data
    FROM sessions
    WHERE id = '$id' AND domain = '$domain' AND agent = '$agent'";

     if ($result = mysql_query($sql, $_sess_db)){

         if (mysql_num_rows($result)){
             $record = mysql_fetch_assoc($result);
             return $record['data'];
        }

    }

    return '';

}

function _write($id, $data){

    global $_sess_db;
    $access = time();

    $id = mysql_real_escape_string($id);
    $access = mysql_real_escape_string($access);
    $data = mysql_real_escape_string($data);
    $domain = mysql_real_escape_string(site_domain);
    $agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));

    $sql = "REPLACE INTO sessions
    VALUES ('$id', '$access', '$data', '$domain', '$agent')";

    return mysql_query($sql, $_sess_db);

}

function _destroy($id){

    global $_sess_db;
    $id = mysql_real_escape_string($id);
    $domain = mysql_real_escape_string(site_domain);
    $agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));

    $sql = "DELETE FROM sessions
    WHERE id = '$id' AND domain = '$domain' AND agent = '$agent'";

    return mysql_query($sql, $_sess_db);

}

function _clean($max){

    global $_sess_db;
    $old = time() - $max;
    $old = mysql_real_escape_string($old);
    $domain = mysql_real_escape_string(site_domain);
    $agent = mysql_real_escape_string(isset($_SERVER['HTTP_USER_AGENT']));

    $sql = "DELETE FROM sessions
    WHERE  access < '$old' AND domain = '$domain' AND agent = '$agent'";

    return mysql_query($sql, $_sess_db);

}

?>

0
Ian

J'ai eu un problème similaire, cependant, cette solution était bonne pour moi, aidera peut-être d'autres à l'avenir

éditer le php.ini

session.cookie_domain = ".example.com"

la magie est là

suhosin.session.cryptdocroot = Off

suhosin.cookie.cryptdocroot = Off

https://www.sitepoint.com/community/t/sessions-across-subdomains-domain-com-phpsessid-changes/3013/19

0
Willian Santana

Essayez simplement d'utiliser le code suivant juste au-dessus de la méthode session_start()

$sess_life_time = 21600; //in seconds
$sess_path = "/";
$sess_domain = ".you-site-name.com";
$sess_secure = true; // if you have secured session
$sess_httponly = true; // httponly flag

session_set_cookie_params($sess_life_time, $sess_path, $sess_domain, $sess_secure, $sess_httponly);
0
mohsin.mr

Je ne peux pas parler d'autres versions de PHP, mais dans la version 5.6.6, définir simplement la valeur session.cookie_domain dans le fichier php.ini permettait à tous mes sous-domaines sur iPage de partager le même ensemble de variables de session. 

Assurez-vous de supprimer tous les cookies existants liés à votre domaine de votre navigateur pour les tester. 

session.cookie_domain = '.yourdomainname.org'

Oh, je ne sais pas si cela fait une différence, mais j'utilise également le démarrage automatique de session. 

session.auto_start = 1
0
user3232196