我正在尝试设置以下内容:
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完全相同但是当我转出$ _SESSION变量时,它不显示两个键,只显示我在每个域下设置的任何键。
[编辑2]
我更新了[编辑]
答案 0 :(得分:129)
我不知道问题是否仍然存在,但我遇到了同样的问题,并在调用session_set_cookie_params()之前解决了设置会话名称的问题:
$some_name = session_name("some_name");
session_set_cookie_params(0, '/', '.some_domain.com');
session_start();
我的php.ini中没有任何改变,但现在一切正常。
答案 1 :(得分:24)
可以神秘地阻止在子域上读取会话数据的一件事,尽管cookie被正确设置为.domain.com
是PHP Suhosin补丁。根据问题中的示例,您可以正确配置所有内容,但它可能无法正常工作。
关闭以下Suhosin会话设置,您又回到了公司:
suhosin.session.cryptua = Off
suhosin.session.cryptdocroot = Off
答案 2 :(得分:5)
尝试使用:
session.cookie_domain = "domain.com"
而不是:
session.cookie_domain = ".domain.com"
请注意缺失的时间段。
小心使用它,因为并非所有浏览器都支持它。
答案 3 :(得分:4)
有这个确切的问题 - 我希望在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(在我的情况下是.local)。 Http协议不允许cookie /会话存储在没有.tld的域上(即localhost不起作用,但stuff.localhost会)。
编辑:还要确保在跨子域测试/调试会话时始终清除浏览器Cookie。如果不这样做,您的浏览器将始终发送可能尚未设置正确cookie_domain的旧会话cookie。服务器将恢复旧会话,因此您将得到错误的否定结果。 (在很多帖子中都提到使用session_name('stuff')来获得完全相同的效果)
答案 4 :(得分:3)
我解决了这个问题
ini_set('session.cookie_domain', '.testdomain.dev');
session_start();
因为我正在使用localhost
ini_set('session.cookie_domain', '.localhost');
无法正常工作,它将.localhost视为toplevel而不是.com / .local / ...(我怀疑)
我也使用.dev,因为在OS X上工作似乎并没有解决.com在HOSTS中的第一次
答案 5 :(得分: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
的路径可能因您的情况而异,但在每个域/子域上应该是相同。默认情况下并非总是如此。
答案 6 :(得分: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
答案 7 :(得分:1)
使用它,它有效:
ini_set('session.cookie_domain',
substr($_SERVER['SERVER_NAME'],strpos($_SERVER['SERVER_NAME'],"."),100));
答案 8 :(得分: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);
?>
答案 9 :(得分:0)
我已经阅读了上面的所有答案,我认为我的答案对于谷歌搜索这个有用。
* 确保浏览器将会话cookie发送回服务器(域和子域),将会话cookie域设置为“.example.com”。
* 确保php找到正确的“目标”来恢复会话var - 如果域和子域指向同一台机器(可能是不同的虚拟主机),请确保“session_save_path”对所有机构都相同(我测试过) - 如果域和子域指向不同的计算机,则公共存储(如数据库)最适合保存和恢复会话数据(我还没有测试)。使用“session_set_save_handler”来做到这一点。
答案 10 :(得分:0)
使用:
session_name("put_a_session_name");
session_start([
"cookie_domain" => ".example.com",
"cookie_path" => "/"
]);
答案 11 :(得分:0)
我不能代表其他版本的PHP,但在5.6.6中,只需在session.cookie_domain
文件中设置php.ini
值,就可以让iPage上的所有子域名共享同一组会话变量。
请务必从浏览器中删除与您的域相关的所有现有Cookie以进行测试。
session.cookie_domain = '.yourdomainname.org'
哦,不知道它是否有任何区别,但我也在使用会话自动启动。
session.auto_start = 1
答案 12 :(得分:0)
我有类似的问题,但是,这个解决方案对我有好处,也许将来会帮助别人
编辑php.ini
session.cookie_domain =“。example.com”
神奇就在这里
suhosin.session.cryptdocroot = Off
suhosin.cookie.cryptdocroot = Off
答案 13 :(得分: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);
答案 14 :(得分: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);
}
&GT;
答案 15 :(得分:0)
我认为你不想像Joel那样想要像OpenID这样的东西,但你希望能够跨多个域访问会话数据。
我认为解决该问题的唯一可能性是将sessiondata存储在数据库中,并将其从该数据库中拉出来。
答案 16 :(得分:-2)
快速而肮脏的解决方案是将其用于重定向:
header( $url.'?'.session_name().'='.session_id() );
这将向URL添加一些内容:PHPSESSID = etnm7kbuf5lg0r6tv7je6ehtn4,它告诉PHP它应该使用的会话ID。