2009-06-30 63 views
80

我試圖建立如下:PHP會議

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

其中,如果用戶訪問sub1.domain.com或sub2.domain.com,他們還沒有登錄,他們將被推轉到auth.domain.com並可以登錄。sub1.domain.com和sub2.domain.com是兩個單獨的應用程序,但使用相同的憑據。

我試着設置以下在我的php.ini:

session.cookie_domain = ".domain.com" 

,但它似乎並沒有從一個領域到另一個傳遞信息。

[編輯]

我嘗試以下:

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

會話ID完全相同,但是當我將$ _SESSI ON變量,它不顯示兩個鍵,就是我在每個域下設置的任何鍵。

[編輯2]

我更新[編輯]

+1

我有幾乎相同的設置(我通過調用「session_set_cookie_params」設置會話cookie域),它工作正常。 – 2009-06-30 15:25:20

+0

您必須在您的代碼中啓用它,請參閱[http://us2.php.net/manual/en/function.session-set-cookie-params.php](http://us2.php.net /manual/en/function.session-set-cookie-params.php) – Residuum 2009-06-30 15:18:58

+0

這裏是不錯的功能,工程 http://stackoverflow.com/questions/2835486/php-session-shared-with-子域/ 17638102#17638102 – boksiora 2013-07-14 09:25:43

回答

4

嘗試使用:

session.cookie_domain = "domain.com" 

相反的:

session.cookie_domain = ".domain.com" 

注意失蹤時期。

但請小心使用它,因爲它不被所有瀏覽器支持。

+8

哪些瀏覽器不受支持? – gawpertron 2011-02-16 19:09:48

+7

什麼瀏覽器支持到這裏?這是服務器端的行爲。 – Kuf 2014-10-20 17:45:15

0

我知道你不想像Openel這樣的東西,就像Joel所建議的那樣,但是你希望跨多個域訪問會話數據。

我可以認爲這個問題的解決方案的唯一可能性是將sessiondata存儲在數據庫中,並將其從數據庫中提取出來。

+0

對,雖然身份驗證是我想要做的一部分,但我也對會話數據感興趣,這些數據在用戶正在工作時被存儲。 – dragonmantank 2009-06-30 18:47:38

-2

一個快速和骯髒的解決辦法是使用你的重定向:

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

這將沿着PHPSESSID = etnm7kbuf5lg0r6tv7je6ehtn4到URL,它告訴它應該使用PHP會話ID的線條添加的東西。

+3

這也使它很容易受到會話盜用:)問題不在於會話ID不匹配(它們是,請參閱我的更新後的帖子),而是數據在域之間不移動。 – dragonmantank 2009-06-30 19:08:48

+0

同意,這是非常脆弱的,在查詢字符串中留下會話ID。 – 2013-02-18 10:02:45

+4

Cookies也以純文本的形式發送,這不會打開任何尚未打開的途徑。我並不是說這是一個很好的解決方案,但它不會比使用cookies更安全。 – sakabako 2013-03-01 19:48:16

124

我不知道,如果問題仍然存在,但我只是碰到了同樣的問題,解決它調用session_set_cookie_params()之前設置一個會話名稱:

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

我已經在我的PHP什麼都沒有改變.ini但現在一切工作正常。

1

利用這一點,它的工作原理:

可以神不知鬼不覺防止被讀取區域上的會話數據,儘管餅乾被正確設定爲 .domain.com
ini_set('session.cookie_domain', 
    substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100)); 
24

一件事是PHP了Suhosin補丁。根據問題中的示例,您可以正確配置所有內容,但它可能無法正常工作。

把下列了Suhosin會話設置關閉,你在企業裏回:

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

我知道這是舊的,但這個工作正常,我有多個域名,並在同一個盒子子域。

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

} 

?>

3

我解決它像這樣

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

因爲我是工作在本地主機

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

沒有工作,它認爲.localhost作爲頂級而不是.com/.local/...(我懷疑)

我也用.dev因爲在OS X上的工作似乎並沒有解決.com作爲第一個在HOSTS

0

我已閱讀上述所有的答案,我想我的答案是人們在Google上搜尋這是很有幫助的。

*確保瀏覽器發送會話cookie回(域和子域)服務器,設置會話cookie域「.example.com的」。

*確保PHP找到恢復會話VAR 右側的「目標」 - 如果域和子域指向同一臺機器(也許不同的虛擬主機),確保「session_save_path」是所有(我一樣測試) - 如果域和子域指向不同的機器,公共存儲(如數據庫)最適合保存和恢復會話數據(我還沒有測試過)。使用「session_set_save_handler」來做到這一點。

2

使用它在每一個站點/子:

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

路徑爲session.save_path可以爲你的情況不同,但它應該是在每個站點/子的相同。默認情況下並非總是如此。

3

有這個確切的問題 - 我想在x.example.local上創建的會話值在example.local上可用,反之亦然。

我找到的所有解決方案都是通過在.htaccess中使用 php_value session.cookie_domain .example.local(或通過php.ini或通過ini_set)更改會話域。

捕捉是我爲所有子域設置session.cookie_domain(迄今爲止),但也爲主域。在主域上設置session.cookie_domain顯然是一個禁忌。

基本上它的方式爲我工作:

  • 設置session.cookie_domain的所有子域。
  • 請勿將其用於主域名

哦,是的,請確保該域有TLD(在我的情況。本地)。 Http協議不允許將cookie /會話存儲在沒有.tld的域中(即localhost不會工作,但是stuff.localhost會)。

編輯:同時確保您始終在跨子域測試/調試會話期間清除瀏覽器Cookie。如果您不這樣做,您的瀏覽器將始終發送舊會話cookie,該cookie可能沒有設置正確的cookie_domain。服務器將恢復舊會話,因此您將得到錯誤的否定結果。 (在很多帖子它提到使用會話名稱(「東西」)的確切效果相同)

0

只需用下面的代碼嘗試略高於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); 
1

子域和根域Cookie的會話聯合應用

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

我測試過的作品

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

exampledomain.com/sessionview.php // 123 

- 代碼

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

我已確認。 joreon的回答是正確的。我不能評論,因爲我的聲譽不夠,所以我在這裏發表我的評論。

在配置文件中定義常量。如果你想改變它,不需要修改整個文件。

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

會話名稱不能只包含數字,至少必須有一個字母。否則,每次都會生成一個新的會話ID。

使用下面的代碼開始使用會話

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

我使用這個功能:

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 
0

我不能代表其他版本的PHP說話,但在5.6.6,簡單地設置在php.ini文件session.cookie_domain值做了讓iPage上的所有子域名共享同一組會話變量的技巧

務必刪除與您的域名相關的任何現有cookie rowser測試。

session.cookie_domain = '.yourdomainname.org' 

哦,不知道它是否有什麼區別,但我也使用會話自動啓動。

session.auto_start = 1