PHP-sessies over subdomeinen

Ik probeer het volgende in te stellen:

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

Als de gebruiker sub1.example.comof sub2.example.combezoekt en niet is ingelogd, wordt hij omgeleid naar auth.example.comen kan inloggen.

sub1.example.comen sub2.example.comzijn twee afzonderlijke applicaties, maar gebruiken dezelfde inloggegevens.

Ik heb geprobeerd het volgende in te stellen in mijn php.ini:

session.cookie_domain = ".example.com"

maar het lijkt erop dat de informatie niet van het ene domein naar het andere wordt doorgegeven.

[Bewerken]

Ik heb het volgende geprobeerd:

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

De sessie-ID’s zijn precies hetzelfde, maar als ik de variabele $_SESSIONdump, worden niet beide sleutels weergegeven, alleen de sleutel die ik onder elk domein instel.


Antwoord 1, autoriteit 100%

Ik weet niet of het probleem nog steeds bestaat, maar ik kwam net hetzelfde probleem tegen en loste het op door een sessienaam in te stellen voordat ik session_set_cookie_params()aanroep:

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

Ik heb niets veranderd in mijn php.inimaar nu werkt alles goed.


Antwoord 2, autoriteit 17%

Een ding dat op mysterieuze wijze kan voorkomen dat sessiegegevens worden gelezen op een subdomein, ondanks dat cookies correct zijn ingesteld op .example.com, is de PHP Suhosin-patch. Je kunt alles correct hebben geconfigureerd, zoals in de voorbeelden in de vraag, en het kan gewoon niet werken.

Schakel de volgende instellingen voor Suhosin-sessies uit en u kunt weer aan de slag:

suhosin.session.cryptua = Off 
suhosin.session.cryptdocroot = Off

Antwoord 3, autoriteit 4%

Probeer het volgende te gebruiken:

session.cookie_domain = "example.com"

In plaats van:

session.cookie_domain = ".example.com"

Let op de ontbrekende punt aan het begin.

Wees hier echter voorzichtig mee, want het wordt niet door alle browsers ondersteund.


Antwoord 4, autoriteit 3%

Heb precies dit probleem gehad: ik wilde dat sessiewaarden die op x.example.local zijn gemaakt, beschikbaar zouden zijn op example.local en omgekeerd.

Alle oplossingen die ik vond, zeiden dat ze het Session-domein moesten wijzigen door gebruik te maken van
php_value session.cookie_domain .example.localin .htaccess (of via php.ini of via ini_set).

Het probleem was dat ik de session.cookie_domaininstelde voor alle subdomeinen (tot nu toe ok) maar ook voor het hoofddomein. Het session.cookie_domaininstellen op het hoofddomein is blijkbaar een no-no.

In principe werkte het voor mij:

  • stel het session.cookie_domainin voor ALLE SUBDOMEINEN.
  • stel het niet in voor het hoofdDOMEIN

O ja, zorg ervoor dat het domein een TLD heeft (in mijn geval .local). Het HTTP-protocol staat niet toe dat cookies/sessies worden opgeslagen op een domein zonder .tld (dwz localhost werkt niet, maar stuff.localhost wel).

BEWERK: zorg er ook voor dat u altijd uw browsercookies wist tijdens het testen/debuggen van sessies op subdomeinen. Als u dit niet doet, zal uw browser altijd de oude sessiecookie verzenden die waarschijnlijk nog niet de juiste cookie_domain heeft ingesteld. De server zal de oude sessie nieuw leven inblazen en daarom krijg je vals-negatieve resultaten. (in veel berichten wordt vermeld om session_name(‘stuff’) te gebruiken voor exact hetzelfde effect)


Antwoord 5, autoriteit 2%

Ik heb het zo opgelost

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

Omdat ik aan localhost werkte

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

werkte niet, het ziet .localhost als het hoogste niveau in plaats van .com/.local/… (vermoed ik)


Antwoord 6, autoriteit 2%

Ik heb het bevestigd. Het antwoord van joreonis correct. Ik kan geen commentaar geven omdat mijn reputatie niet genoeg is, dus plaats ik mijn commentaar hier.

Definieer de constante in een configuratiebestand. Als u het wilt wijzigen, hoeft u geen hele bestanden aan te passen.

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

De sessienaam mag niet alleen uit cijfers bestaan, er moet minimaal één letter aanwezig zijn. Anders wordt er elke keer een nieuwe sessie-ID gegenereerd.

Gebruik de volgende code om sessie te starten

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

Ik gebruik deze functie:

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

Antwoord 7

Gebruik het op elk domein/subdomein:

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

Het pad voor session.save_pathkan in uw geval anders zijn, maar het zou op elk domein/subdomein hetzelfdemoeten zijn. Het is standaard niet altijd waar.


Antwoord 8

Gebruik dit, het werkt:

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

Antwoord 9

Subdomein en rootdomein Cookiesessies gecombineerd gebruik

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

Ik heb werken getest

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

Antwoord 10

Ik krijg het idee dat je niet zoiets als OpenID wilt, zoals Joel suggereert, maar dat je toegang wilt hebben tot de sessiegegevens over meerdere domeinen.

De enige mogelijkheid die ik kan bedenken als een oplossing voor dat probleem is om de sessiegegevens in een database op te slaan en uit die database te halen.


Antwoord 11

Ik had een soortgelijk probleem, maar deze oplossing was goed voor mij, misschien zal het anderen in de toekomst helpen

bewerk de php.ini

session.cookie_domain = “.example.com”

de magie is hier

suhosin.session.cryptdocroot = Off
suhosin.cookie.cryptdocroot = Off

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


Antwoord 12

Ik kan niet spreken voor andere versies van PHP, maar in 5.6.6 was het eenvoudig om de session.cookie_domainwaarde in het php.inibestand in te stellen. om al mijn subdomeinen op iPage dezelfde set sessievariabelen te laten delen.

Zorg ervoor dat u alle bestaande cookies met betrekking tot uw domein uit uw browser verwijdert om te testen.

session.cookie_domain = '.yourdomainname.example'

O, ik weet niet of het enig verschil maakt, maar ik gebruik ook sessie autostart.

session.auto_start = 1

Antwoord 13

Probeer gewoon de volgende code te gebruiken net boven de session_start()methode

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

Antwoord 14

Ik heb alle bovenstaande antwoorden gelezen, ik denk dat mijn antwoord nuttig is voor mensen die dit googelen:

  • zorg ervoor dat de browser de sessiecookie terugstuurt naar de servers (van domein en subdomeinen), stel het sessiecookiedomein in als .example.com.

  • Zorg ervoor dat PHP het juiste “doel” vindt om de sessievariabele te herstellen:

    • Als domein en subdomeinen naar dezelfde machine verwijzen (misschien verschillende virtuele hosts), zorg er dan voor dat session_save_pathvoor iedereen hetzelfde is (ik heb getest)
    • Als domein en subdomeinen naar verschillende machines verwijzen, is de gemeenschappelijke opslag (zoals database) het beste voor het opslaan en herstellen van sessiegegevens (ik heb het nog niet getest). Gebruik session_set_save_handlerom dat te doen.

Antwoord 15

Ik weet dat dit oud is, maar dit werkt prima voor mij met meerdere domeinen en subdomeinen op dezelfde 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);
}

?>


Antwoord 16

Gebruik:

session_name("put_a_session_name");
session_start([
  "cookie_domain" => ".example.com",
  "cookie_path" => "/"
]);

Antwoord 17

Een snelle en vuile oplossing is om dit te gebruiken voor uw omleiding:

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

dit voegt iets in de trant van ?PHPSESSID=etnm7kbuf5lg0r6tv7je6ehtn4toe aan de URL, die PHP vertelt welk sessie-ID het moet gebruiken.

Other episodes