PHP-Sitzungen über Subdomains hinweg

92

Ich versuche Folgendes einzurichten:

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

Wenn der Benutzer sub1.example.comoder besucht sub2.example.comund nicht angemeldet ist, wird er zu weitergeleitet auth.example.comund kann sich anmelden.

sub1.example.comund sub2.example.comsind zwei separate Anwendungen, verwenden jedoch dieselben Anmeldeinformationen.

Ich habe versucht, Folgendes in meiner php.ini einzustellen:

session.cookie_domain = ".example.com"

Es scheint jedoch nicht, dass die Informationen von einer Domäne an die andere weitergegeben werden.

[Bearbeiten]

Ich habe folgendes versucht:

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);

Die Sitzungs-IDs sind genau gleich, aber wenn ich die $_SESSIONVariable ausgeben möchte, werden nicht beide Schlüssel angezeigt, nur der Schlüssel, den ich unter jeder Domäne festgelegt habe.

Drachenmantel
quelle
Sie müssen es auch in Ihrem Code aktivieren, siehe http://us2.php.net/manual/en/function.session-set-cookie-params.php
Residuum
1
Ich habe fast das gleiche Setup (ich habe die Sitzungscookie-Domäne mit einem Aufruf von "session_set_cookie_params" festgelegt) und es funktioniert einwandfrei.
Milen A. Radev
Hier ist eine nette Funktion, die funktioniert stackoverflow.com/questions/2835486/…
boksiora

Antworten:

134

Ich weiß nicht, ob das Problem noch besteht, aber ich bin auf dasselbe Problem gestoßen und habe es gelöst, indem ich vor dem Aufruf einen Sitzungsnamen festgelegt habe session_set_cookie_params():

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

Ich habe nichts an meinem geändert, php.iniaber jetzt funktioniert alles gut.

Jeroen
quelle
10
Ich bestätige, es löst das Problem. Ich war müde, meine Antwort dort zu bekommen: stackoverflow.com/questions/4948340/… . Aber ich habe es hier gefunden.
Roman
5
Funktioniert perfekt! Ich habe lange danach gesucht. Es war das $some_name = session_name("some_name");, was es getan hat. Vielen Dank und positive Bewertung.
Kit
4
Das Hinzufügen session_name("domain");war auch für mich die fehlende Zutat. Die Dokumentation auf php.net zu diesen Sitzungseinstellungen fehlt. Es gibt Community-Beiträge auf php.net, die angeben, dass session.name definiert werden muss, bevor Änderungen an session_set_cookie_params () angewendet werden können.
David Carroll
3
ja. Bestätigt. nett ging dort
Daithí
1
HINWEIS ... musste meinen Browser schließen und neu starten, damit er auf dem Life Server funktioniert. Lassen Sie alle ini_set("session.cookie_domain", ".domain.com");Gründe aus, die dazu geführt haben, dass bei jeder Aktualisierung eine neue Sitzungs-ID erstellt wurde.
Daithí
24

Eine Sache, die auf mysteriöse Weise verhindern kann, dass Sitzungsdaten in einer Subdomain gelesen werden, obwohl Cookies korrekt eingestellt sind, .example.comist der PHP-Suhosin-Patch. Sie können alles gemäß den Beispielen in der Frage richtig konfigurieren lassen, und es kann einfach nicht funktionieren.

Schalten Sie die folgenden Suhosin-Sitzungseinstellungen aus und Sie sind wieder im Geschäft:

suhosin.session.cryptua = Off 
suhosin.session.cryptdocroot = Off
Drawm
quelle
5

Versuchen Sie es mit:

session.cookie_domain = "example.com"

Anstatt:

session.cookie_domain = ".example.com"

Beachten Sie den fehlenden Zeitraum zu Beginn.

Seien Sie jedoch vorsichtig, da dies nicht von allen Browsern unterstützt wird.

George Claghorn
quelle
9
Welche Browser werden nicht unterstützt?
Gawpertron
10
Welche Browserunterstützung muss hier sein? Dies ist eine serverseitige Aktion.
Kuf
4

Hatte genau dieses Problem - ich wollte, dass auf x.example.local erstellte Sitzungswerte auf example.local verfügbar sind und umgekehrt.

Alle Lösungen, die ich gefunden habe, sollen die Sitzungsdomäne mithilfe php_value session.cookie_domain .example.localvon .htaccess (oder über php.ini oder über ini_set) ändern.

Der Haken war, dass ich das session.cookie_domainfür alle Subdomains (bisher ok), aber auch für die Hauptdomain eingestellt habe. Das Festlegen der session.cookie_domainauf der Hauptdomäne ist anscheinend ein Nein-Nein.

Grundsätzlich hat es bei mir so funktioniert:

  • session.cookie_domainStellen Sie die für ALLE SUBDOMAINS ein.
  • Stellen Sie es nicht für die Hauptdomäne ein

Oh ja, bitte stellen Sie sicher, dass die Domain eine TLD hat (in meinem Fall .local). Das HTTP-Protokoll erlaubt nicht, dass Cookies / Sitzungen in einer Domain ohne .tld gespeichert werden (dh localhost funktioniert nicht, stuff.localhost jedoch).

BEARBEITEN : Stellen Sie außerdem sicher, dass Sie Ihre Browser-Cookies immer löschen, während Sie Sitzungen über Subdomänen hinweg testen / debuggen. Wenn Sie dies nicht tun, sendet Ihr Browser immer das alte Sitzungscookie, für das wahrscheinlich noch nicht die richtige cookie_domain festgelegt ist. Der Server wird die alte Sitzung wiederbeleben und daher erhalten Sie falsch negative Ergebnisse. (In vielen Posts wird erwähnt, dass session_name ('stuff') für genau den gleichen Effekt verwendet wird.)

Valentin Florea
quelle
3

Ich habe es so gelöst

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

Weil ich an localhost gearbeitet habe

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

funktionierte nicht , es sieht .localhost als oberste Ebene anstelle von .com / .local / ... (ich vermute)

xtds
quelle
Auch behoben für meine Maschine - Ubuntu 14.04
Dennis
3

Ich habe bestätigt. Joreons Antwort ist richtig. Ich kann keinen Kommentar abgeben, da mein Ruf nicht ausreicht. Deshalb poste ich meinen Kommentar hier.

Definieren Sie die Konstante in einer Konfigurationsdatei. Wenn Sie es ändern möchten, müssen Sie nicht ganze Dateien ändern.

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

Der Sitzungsname darf nicht nur aus Ziffern bestehen, es muss mindestens ein Buchstabe vorhanden sein. Andernfalls wird jedes Mal eine neue Sitzungs-ID generiert.

Verwenden Sie den folgenden Code, um die Sitzung zu starten

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

Ich benutze diese Funktion:

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
quelle
2

Verwenden Sie es für jede Domain / Subdomain:

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

Pfad für die session.save_pathfür Ihren Fall unterschiedlich sein , aber es sollte das sein gleiche auf jeder Domain / Subdomain. Dies ist standardmäßig nicht immer der Fall.

Andrii Nemchenko
quelle
1

Verwenden Sie dies, es funktioniert:

ini_set('session.cookie_domain', 
    substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
Ivan
quelle
das sieht so aus, als würde es den Cookie für das tld setzen ... oder fehlt mir etwas?
Chacham15
1

Kombinierte Verwendung von Cookie-Sitzungen für Subdomänen und Stammdomänen

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

Ich habe Werke getestet

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); 
?>
Grenzenlose isa
quelle
0

Ich habe die Idee, dass Sie nicht so etwas wie OpenID wollen, wie Joel vorschlägt, sondern dass Sie über mehrere Domänen hinweg Zugriff auf die Sitzungsdaten haben möchten.

Die einzige Möglichkeit, die ich mir als Lösung für dieses Problem vorstellen kann, besteht darin, die Sitzungsdaten in einer Datenbank zu speichern und aus dieser Datenbank zu ziehen.

Thomas
quelle
Richtig, während die Authentifizierung ein Teil meiner Arbeit ist, interessieren mich auch die Sitzungsdaten, die gespeichert werden, während der Benutzer arbeitet.
Drachenmantel
0

Ich kann nicht für andere Versionen von PHP sprechen, aber in 5.6.6 hat das einfache Festlegen des session.cookie_domainWerts in der php.iniDatei dazu beigetragen, dass alle meine Subdomains auf iPage denselben Satz von Sitzungsvariablen gemeinsam nutzen konnten.

Entfernen Sie zum Testen alle vorhandenen Cookies, die sich auf Ihre Domain beziehen, aus Ihrem Browser.

session.cookie_domain = '.yourdomainname.example'

Oh, ich weiß nicht, ob es einen Unterschied macht, aber ich verwende auch den automatischen Sitzungsstart.

session.auto_start = 1
user3232196
quelle
0

Versuchen Sie einfach, den folgenden Code direkt über der session_start()Methode zu verwenden

$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
quelle
0

Ich habe alle Antworten oben gelesen. Ich denke, meine Antwort ist hilfreich für Leute, die dies googeln:

  • Stellen Sie sicher, dass die Browser Sitzungscookies an Server (von Domänen und Subdomänen) zurücksenden, und legen Sie die Sitzungscookie-Domäne als fest .example.com.

  • Stellen Sie sicher, dass PHP das richtige "Ziel" findet, um die Sitzungsvariable wiederherzustellen:

    • Wenn Domain und Subdomains auf denselben Computer verweisen (möglicherweise unterschiedliche virtuelle Hosts), stellen Sie sicher, dass session_save_pathalle für alle gleich sind (ich habe getestet).
    • Wenn Domain und Subdomains auf unterschiedliche Computer verweisen, eignet sich der gemeinsame Speicher (wie die Datenbank) am besten zum Speichern und Wiederherstellen von Sitzungsdaten (ich habe noch nicht getestet). Verwenden Sie session_set_save_handlerdazu.
user953985
quelle
0

Ich weiß, dass dies alt ist, aber dies funktioniert gut für mich mit mehreren Domains und Subdomains auf derselben Box.

<?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
quelle
6
Welche Frage beantwortest du? Und wie verbessert / verbessert dies die 9 anderen Antworten?
random_user_name
0

Verwenden :

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

Eine schnelle und schmutzige Lösung besteht darin, dies für Ihre Weiterleitung zu verwenden:

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

Dadurch wird ?PHPSESSID=etnm7kbuf5lg0r6tv7je6ehtn4der URL etwas hinzugefügt , das PHP die Sitzungs-ID mitteilt, die es verwenden soll.

Sakabako
quelle
3
Außerdem ist es sehr anfällig für Sitzungsdiebstahl :) Das Problem liegt nicht darin, dass die Sitzungs-IDs nicht übereinstimmen (siehe meinen aktualisierten Beitrag), sondern dass sich die Daten nicht zwischen den Domänen bewegen.
Drachenmantel
Einverstanden ist dies sehr anfällig, wenn die Sitzungs-ID in der Abfragezeichenfolge verbleibt.
Ian Jamieson
4
Cookies werden auch als Klartext gesendet. Dadurch werden keine noch nicht geöffneten Wege geöffnet. Ich sage nicht, dass es eine gute Lösung ist, aber es ist nicht weniger sicher als die Verwendung von Cookies.
Sakabako
1
Es ist weniger sicher in dem Sinne, dass Benutzer möglicherweise ihre URL freigeben und somit ihre aktive Sitzungs-ID freigeben. Es ist viel weniger wahrscheinlich, dass ein Benutzer sein Sitzungs-ID-Cookie unabsichtlich weitergibt.
Bastiaan zehn Klooster