Alt etki alanlarında PHP Oturumları


92

Aşağıdakileri kurmaya çalışıyorum:

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

Kullanıcı sub1.example.comveya ziyaret ederse ve sub2.example.comoturum açmadıysa, adresine yönlendirilir auth.example.comve oturum açabilir.

sub1.example.comve sub2.example.comiki ayrı uygulamadır ancak aynı kimlik bilgilerini kullanır.

Php.ini dosyamda aşağıdakileri ayarlamayı denedim:

session.cookie_domain = ".example.com"

ancak bilgileri bir alandan diğerine aktarıyor gibi görünmüyor.

[Düzenle]

Aşağıdakileri denedim:

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

Oturum kimlikleri tam olarak aynıdır, ancak $_SESSIONdeğişkeni attığımda her iki anahtarı da göstermiyor, her etki alanı altında ayarladığım anahtar ne olursa olsun.



1
Neredeyse aynı kuruluma sahibim ("session_set_cookie_params" çağrısıyla oturum tanımlama bilgisi alanını ayarladım) ve iyi çalışıyor.
Milen A. Radev

Yanıtlar:


134

Sorunun hala devam edip etmediğini bilmiyorum, ancak aynı sorunla karşılaştım ve aramadan önce bir oturum adı belirleyerek çözdüm session_set_cookie_params():

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

Benim içinde hiçbir php.inişeyi değiştirmedim ama şimdi her şey yolunda gidiyor.


10
Onaylıyorum, sorunu çözüyor. Cevabımı orada almaktan yoruldum: stackoverflow.com/questions/4948340/… . Ama burada buldum.
Roman

5
Mükemmel çalışıyor! Bunun için yaşları arıyordum. Bunu yapan oydu $some_name = session_name("some_name");. Teşekkürler ve oy verin.
Kit

4
Eklemek session_name("domain");benim için de eksik olan malzemeydi. Bu oturum ayarlarıyla ilgili php.net'teki belgeler eksiktir. Php.net'te, session_set_cookie_params () değişiklikleri uygulanmadan önce session.name'nin tanımlanması gerektiğini belirten topluluk gönderileri var.
David Carroll

3
Evet. onaylanmış. güzel bir tane yaş için çevrelerinde etrafında gidiyordu;)
Daithí

1
NOT ... hayat sunucusunda çalışması için tarayıcımı kapatıp yeniden başlatmam gerekti. ini_set("session.cookie_domain", ".domain.com");Her yenilemede yeni oturum kimliği oluşturmasına neden olan herhangi bir nedeni dışarıda bırakın .
Daithí

24

Çerezlerin doğru bir şekilde ayarlanmasına rağmen, oturum verilerinin bir alt etki alanında okunmasını gizemli bir şekilde engelleyebilecek bir şey .example.com, PHP Suhosin yamasıdır. Sorudaki örneklere göre her şeyi doğru şekilde yapılandırabilirsiniz ve bu işe yaramaz.

Aşağıdaki Suhosin oturum ayarlarını kapatın ve işinize geri dönün:

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

5

Şunları kullanmayı deneyin:

session.cookie_domain = "example.com"

Onun yerine:

session.cookie_domain = ".example.com"

Başlangıçta eksik noktaya dikkat edin.

Ancak bunu kullanırken dikkatli olun, çünkü tüm tarayıcılar tarafından desteklenmemektedir.


9
Hangi tarayıcılar desteklenmiyor?
gawpertron

10
Burada hangi tarayıcı desteği gerekiyor? bu bir sunucu tarafı işlemidir.
Kuf

4

Tam olarak bu sorunu yaşadım - x.example.local üzerinde oluşturulan oturum değerlerinin example.local üzerinde mevcut olmasını istedim ve tam tersi.

Bulduğum tüm çözümler php_value session.cookie_domain .example.local.htaccess kullanarak (veya php.ini veya ini_set aracılığıyla) Oturum etki alanını değiştirmeyi söyledi .

İşin püf noktası, session.cookie_domaintüm alt alan adları için (şimdiye kadar tamam) ama aynı zamanda ana alan için ayarlıyordum . session.cookie_domainAna etki alanında ayarlamak görünüşe göre hayır-hayır.

Temelde benim için çalışma şekli:

  • set session.cookie_domaintüm alt alanların.
  • ana DOMAIN için ayarlamayın

Oh evet, lütfen etki alanının bir TLD'ye sahip olduğundan emin olun (benim durumumda .local). Http protokolü, tanımlama bilgilerinin / oturumların .tld olmadan bir etki alanında depolanmasına izin vermez (yani localhost çalışmaz, ancak stuff.localhost çalışacaktır).

DÜZENLEME : Ayrıca, alt alanlardaki oturumları test ederken / hata ayıklarken tarayıcı çerezlerinizi her zaman temizlediğinizden emin olun. Bunu yapmazsanız, tarayıcınız her zaman muhtemelen henüz doğru cookie_domain ayarına sahip olmayan eski oturum çerezini gönderir. Sunucu eski oturumu canlandıracak ve bu nedenle yanlış negatif sonuçlar alacaksınız. (birçok gönderide aynı etki için session_name ('stuff') kullanmaktan bahsedilir)


3

Bunu böyle çözdüm

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

Çünkü localhost üzerinde çalışıyordum

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

çalışmıyor , .com / .local / ... yerine .localhost'u üst düzey olarak görüyor (sanırım)


Ayrıca makinem için de düzeltildi - Ubuntu 14.04
dennis

3

Onayladım. joreon 'un cevabı doğru. İtibarım yeterli olmadığı için yorum yapamam, bu yüzden yorumumu buraya yazıyorum.

Sabiti bir yapılandırma dosyasında tanımlayın. Değiştirmek istiyorsanız, tüm dosyaları değiştirmenize gerek yoktur.

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

Oturum adı yalnızca rakamlardan oluşamaz, en az bir harf bulunmalıdır. Aksi takdirde, her seferinde yeni bir oturum kimliği oluşturulur.

Oturumu kullanmaya başlamak için aşağıdaki kodu kullanın

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

Bu işlevi kullanıyorum:

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

2

Her etki alanında / alt etki alanında kullanın:

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

Yol, session.save_pathsizin durumunuz için farklı olabilir, ancak her alan / alt alan adında aynı olmalıdır . Varsayılan olarak her zaman doğru değildir.


1

Bunu kullanın, işe yarıyor:

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

bu tld için çerezi ayarlıyor gibi görünüyor ... yoksa bir şey mi kaçırıyorum?
chacham15

1

Alt alan ve kök alan Tanımlama Bilgisi Oturumları Birleşik Kullanım

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

İşleri test ettim

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

example.com/sessionview.php // 123

- Kodlar

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

0

Joel'in önerdiği gibi OpenID gibi bir şey istemediğiniz fikrine kapıldım, ancak birden çok alanda oturum verilerine erişmek istediğinizi anlıyorum.

Bu soruna çözüm olarak düşünebildiğim tek olasılık, oturum verilerini bir veritabanında depolamak ve bu veritabanından çıkarmak.


Doğru, kimlik doğrulama yapmak istediğim şeyin bir parçası olsa da, kullanıcı çalışırken depolanan oturum verileriyle de ilgileniyorum.
dragonmantank


0

PHP'nin diğer sürümleri için konuşamam, ancak 5.6.6'da, basitçe dosyadaki session.cookie_domaindeğeri ayarlamak, php.iniiPage üzerindeki tüm alt etki alanlarımın aynı oturum değişkenlerini paylaşmasına izin vermek için hile yaptı.

Etki alanınızla ilgili mevcut çerezleri test etmek için tarayıcınızdan kaldırdığınızdan emin olun.

session.cookie_domain = '.yourdomainname.example'

Oh, bir fark yaratır mı bilmiyorum ama aynı zamanda otomatik oturum başlatmayı da kullanıyorum.

session.auto_start = 1

0

session_start()Yöntemin hemen yukarısındaki aşağıdaki kodu kullanmayı deneyin

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

0

Yukarıdaki tüm cevapları okudum, cevabımın bunu araştıran insanlar için faydalı olduğunu düşünüyorum:

  • tarayıcıların oturum tanımlama bilgisini sunuculara (etki alanı ve alt etki alanları) geri gönderdiğinden emin olun, oturum tanımlama bilgisi etki alanını olarak ayarlayın .example.com.

  • PHP'nin oturum değişkenini geri yüklemek için doğru "hedefi" bulduğundan emin olun:

    • Etki alanı ve alt etki alanları aynı makineyi gösteriyorsa (belki farklı sanal ana bilgisayarlar), emin olun session_save_path tümü için aynı (test ettim)
    • Etki alanı ve alt etki alanları farklı makineleri işaret ediyorsa, ortak depolama alanı (veritabanı gibi) oturum verilerini kaydetmek ve geri yüklemek için en iyisidir (henüz test etmedim). session_set_save_handlerBunu yapmak için kullanın .

0

Bunun eski olduğunu biliyorum ama bu, aynı kutuda birden çok alan ve alt alan adıyla benim için iyi çalışıyor.

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

}

?>


6
Hangi soruyu cevaplıyorsunuz? Ve bu diğer 9 yanıtı nasıl geliştirir / geliştirir?
random_user_name

0

Kullanım:

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

-2

Hızlı ve kirli bir çözüm, yönlendirmeniz için bunu kullanmaktır:

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

bu ?PHPSESSID=etnm7kbuf5lg0r6tv7je6ehtn4, URL'nin satırları boyunca PHP'ye kullanması gereken oturum kimliğini söyleyen bir şey ekler .


3
Aynı zamanda onu oturum hırsızlığına karşı oldukça savunmasız bırakır :) Sorun, uyuşmayan oturum kimlikleriyle değil (bunlar, güncellenmiş gönderime bakın), ancak veriler etki alanları arasında hareket etmiyor.
dragonmantank

Kabul edildi, bu, sorgu dizesinde oturum kimliği bırakarak oldukça savunmasızdır.
Ian Jamieson

4
Çerezler de düz metin olarak gönderilir, bu zaten açık olmayan hiçbir yolu açmaz. Bunun iyi bir çözüm olduğunu söylemiyorum, ancak tanımlama bilgilerini kullanmaktan daha az güvenli değil.
sakabako 01

1
Kullanıcıların URL'lerini paylaşmaları (kandırılmaları) ve dolayısıyla aktif oturum kimliklerini paylaşmaları açısından daha az güvenlidir. Bir kullanıcının, oturum kimliği çerezini farkında olmadan paylaşması çok daha az olasıdır.
Bastiaan ten Klooster
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.