Sessions PHP dans les sous-domaines

92

J'essaye de configurer les éléments suivants:

auth.example.com
sub1.example.com
sub2.example.com

Si l'utilisateur visite sub1.example.comou sub2.example.comet qu'il n'est pas connecté, il est redirigé vers auth.example.comet peut se connecter.

sub1.example.comet sub2.example.comsont 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 = ".example.com"

mais il ne semble pas transmettre les informations d'un domaine à l'autre.

[Éditer]

J'ai essayé ce qui suit:

sub1.example.com/test.php

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

auth.example.com/test.php

session_set_cookie_params(0, '/', '.example.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 $_SESSIONvariable, les deux clés ne sont pas affichées, quelle que soit la clé que j'ai définie sous chaque domaine.

dragonmantank
la source
Vous devez également l'activer dans votre code, voir http://us2.php.net/manual/en/function.session-set-cookie-params.php
Residuum
1
J'ai presque la même configuration (j'ai défini le domaine des cookies de session avec un appel à "session_set_cookie_params") et cela fonctionne très bien.
Milen A. Radev
Voici une belle fonction qui fonctionne stackoverflow.com/questions/2835486/…
boksiora

Réponses:

134

Je ne sais pas si le problème existe toujours, mais je viens de rencontrer 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, '/', '.example.com');
session_start();

Je n'ai rien changé à mon php.inimais maintenant tout fonctionne bien.

jeroen
la source
10
Je confirme, cela résout le problème. Je suis fatigué d'obtenir ma réponse là-bas: stackoverflow.com/questions/4948340/… . Mais je l'ai trouvé ici.
Roman
5
Fonctionne parfaitement! Je cherchais cela depuis des lustres. C'est le $some_name = session_name("some_name");qui l'a fait. Merci et vote favorable.
Kit du
4
L'ajout session_name("domain");était aussi l'ingrédient manquant pour moi. La documentation sur php.net concernant ces paramètres de session fait défaut. Il y a des messages de la communauté sur php.net qui indiquent que session.name doit être défini avant que les modifications apportées à session_set_cookie_params () puissent être appliquées.
David Carroll
3
oui. confirmé. le gentil a tourné en rond pendant des siècles là-bas;)
Daithí
1
REMARQUE ... j'ai dû fermer mon navigateur et redémarrer pour le faire fonctionner sur le serveur Life. Laissez de côté toute ini_set("session.cookie_domain", ".domain.com");cause qui l'a amené à créer un nouvel identifiant de session à chaque actualisation.
Daithí
24

Une chose qui peut mystérieusement empêcher la lecture des données de session sur un sous-domaine, bien que les cookies soient correctement définis sur .example.com est le patch PHP Suhosin. Vous pouvez avoir tout configuré correctement, selon les exemples de la question, et cela ne peut tout simplement pas fonctionner.

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

suhosin.session.cryptua = Off 
suhosin.session.cryptdocroot = Off
dessiner
la source
5

Essayez d'utiliser:

session.cookie_domain = "example.com"

Au lieu de:

session.cookie_domain = ".example.com"

Notez la période manquante au début.

Soyez prudent lorsque vous utilisez ceci, car il n'est pas pris en charge par tous les navigateurs.

George Claghorn
la source
9
Quels navigateurs ne sont pas pris en charge?
gawpertron
10
quel support de navigateur doit ici? c'est une action côté serveur.
Kuf
4

Eu 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 indiquaient de changer le domaine de session en utilisant php_value session.cookie_domain .example.local dans .htaccess (ou via php.ini ou via ini_set).

Le hic était que je définissais le session.cookie_domainpour tous les sous-domaines (jusqu'ici ok) mais aussi pour le domaine principal. Définir le session.cookie_domainsur le domaine principal est apparemment un non-non.

Fondamentalement, la façon dont cela a fonctionné pour moi:

  • réglez le session.cookie_domainpour TOUS LES SOUS-DOMAINES.
  • ne le définissez 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 stuff.localhost le fera).

MODIFIER : assurez-vous également de toujours effacer les cookies de votre navigateur lors du test / débogage des sessions sur les 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_domaine correct. Le serveur relancera l'ancienne session et vous obtiendrez donc de faux résultats négatifs. (dans de nombreux articles, il est mentionné d'utiliser session_name ('stuff') pour exactement le même effet)

Valentin Florea
la source
3

Je l'ai résolu comme ça

ini_set('session.cookie_domain', '.testdomain.example');
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 suppose)

xtds
la source
Également corrigé pour ma machine - Ubuntu 14.04
dennis
3

J'ai confirmé. La réponse de joreon est correcte. Je ne peux pas commenter car ma réputation ne suffit pas alors je poste mon commentaire ici.

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

define('ROOT_DOMAIN',   'mysite.example');
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();
    } elseif (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
Terry Lin
la source
2

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_pathpeut être différent pour votre cas, mais il doit être le même sur chaque domaine / sous-domaine. Ce n'est pas toujours vrai par défaut.

Andrii Nemchenko
la source
1

Utilisez ceci, cela fonctionne:

ini_set('session.cookie_domain', 
    substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
Ivan
la source
cela ressemble à son réglage du cookie pour le tld ... ou est-ce que je manque quelque chose?
chacham15
1

Utilisation combinée de sessions de cookies de sous-domaine et de domaine racine

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

J'ai testé des oeuvres

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

example.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); 
?>
Isa illimité
la source
0

J'ai l'idée 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 considérer comme une solution à ce problème est de stocker les données de session dans une base de données et de les extraire de cette base de données.

Thomas
la source
Bien que l'authentification fasse partie de ce que je veux faire, je m'intéresse également aux données de session qui sont stockées pendant que l'utilisateur travaille.
dragonmantank
0

Je ne peux pas parler pour d'autres versions de PHP, mais en 5.6.6, le simple fait de définir la session.cookie_domainvaleur dans le php.inifichier a fait l'affaire pour permettre à 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 tester.

session.cookie_domain = '.yourdomainname.example'

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
user3232196
la source
0

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

$sess_life_time = 21600; //in seconds
$sess_path = "/";
$sess_domain = ".example.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);
mohsin.mr
la source
0

J'ai lu toutes les réponses ci-dessus, je pense que ma réponse est utile pour les personnes qui recherchent ceci:

  • assurez-vous que les navigateurs renvoient le cookie de session aux serveurs (du domaine et des sous-domaines), définissez le domaine du cookie de session sur .example.com.

  • Assurez-vous que PHP trouve la bonne "cible" pour restaurer la variable de session:

    • Si le domaine et les sous-domaines pointent vers la même machine (peut-être des hôtes virtuels différents), assurez-vous session_save_path c'est le même pour tous (j'ai testé)
    • Si le domaine et les sous-domaines pointent vers des machines différentes, le stockage commun (comme la base de données) est le meilleur pour enregistrer et restaurer les données de session (je n'ai pas encore testé). Utilisez session_set_save_handlerpour faire ça.
user953985
la source
0

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

<?php
define('site_domain','example.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);

}

?>

Ian
la source
6
A quelle question répondez-vous? Et comment cela améliore-t-il / améliore-t-il les 9 autres réponses?
random_user_name
0

Utilisation :

session_name("put_a_session_name");
session_start([
  "cookie_domain" => ".example.com",
  "cookie_path" => "/"
]);
Shakil Ahmmed
la source
-2

Une solution rapide et sale consiste à utiliser ceci pour votre redirection:

header( $url.'?'.session_name().'='.session_id() );

cela ajoutera quelque chose comme ?PHPSESSID=etnm7kbuf5lg0r6tv7je6ehtn4à l'URL, qui indiquera à PHP l'ID de session qu'il doit utiliser.

Sakabako
la source
3
Cela le rend également très vulnérable au vol de session :) Le problème n'est pas avec les identifiants de session qui ne correspondent pas (ils le sont, voir mon article mis à jour), mais avec les données ne se déplaçant pas entre les domaines.
dragonmantank
D'accord, cela est très vulnérable en laissant l'ID de session dans la chaîne de requête.
Ian Jamieson
4
Les cookies sont également envoyés sous forme de texte brut, cela n'ouvre aucune voie qui n'était pas déjà ouverte. Je ne dis pas que c'est une bonne solution, mais ce n'est pas moins sûr que l'utilisation de cookies.
sakabako
1
Il est moins sécurisé dans le sens où les utilisateurs peuvent être (amenés à) partager leur URL et ainsi partager leur ID de session actif. Il est beaucoup moins probable qu'un utilisateur partage son cookie d'identification de session sans le vouloir.
Bastiaan ten Klooster