允许php会话继承到子域


75

我对所有用户数据使用php会话(会话ID cookie除外,不是cookie),并且当用户进入其个人资料user.mydomain.com时,他们将立即“注销”,直到删除子域。

只要* .mydomain.com,有没有办法接受来自所有域的会话


1
首先,ini_set('session.cookie_domain', '.example.com')然后 session_start()Session::start()github.com/delight-im/PHP-Cookie
CAW

Answers:


94

这是4个选项。

将其放在您的php.ini中:

session.cookie_domain = ".example.com"

或在您的.htaccess中:

php_value session.cookie_domain .example.com

或作为脚本的第一件事:

ini_set('session.cookie_domain', '.example.com' );

或在您网站的php-fpm池配置中:

php_value[session.cookie_domain] = .example.com

2
不幸的是,这3个人均无法正常工作,是否需要加星号*?
安东尼

2
非常奇怪,我以前使用过那些方法,而且效果很好。您是否偶然安装了Suhosin,我记得需要更改某个设置以允许此操作吗?如果不这样做,是否可以发布有关安装的更多信息(例如apache,lighttpd,php版本)?
CTT

4
@CTT,请在您的答案中添加第四个选项: session_set_cookie_params(0, '/', 'example.com', false, false);
神圣的袜子

7
不要忘记实际关闭浏览器,然后再次打开它。否则你会转圈!..我做到了
AndrewC

9
另一个提醒给像我这样愚蠢的人:请确保ini_set('session.cookie_domain', '.example.com');在此之前 session_start();
Ben Y

13
        if(isset($_COOKIE['session_id']))
            session_id($_COOKIE['session_id']);
        Zend_Session::start(); //or session_start();
        if(!isset($_COOKIE['session_id']))
            setcookie('session_id', session_id(), 0, '/', '.yourdomain.com');

安全,该死的,如果您像我一样对不完整或错误的答案感到沮丧,这就是您的救星。它就是有效的。


3
这对我有用,但我不了解安全问题。您介意解释那里可能存在哪些安全问题吗?
新的

5

更改核心功能文件顶部的会话名称,例如

 session_name('mysession');

然后使用以下代码进入php页面

  session_set_cookie_params(0,"/",".example.com",FALSE,FALSE);
  setcookie(session_name(), session_id(),0,"/","example.com");
  session_start();

最后更改子域的默认会话名称,并删除子域的核心功能文件中的默认cookie,例如:

 /*default session name*/
 session_name("mysession");
 /*remove the PHPSESSID and default session name from subdomain's cookie*/
 setcookie( "mysession", "",1,"/" );
 setcookie( "PHPSESSID", "",1,"/" );

如果您继续使用cookie名称作为PHPSESSID,只需删除带有

 "mysession" string like session_name('mysession'), setcookie( "mysession", "",1,"/" );

然后检查您浏览器的现有Cookie,只需删除域和子域的所有Cookie,然后重复此过程即可。


这为我做了工作。此问题中的其他答案均无效。
Art Geigel '02

4

我知道这已经很老了-但是要进一步扩展@CTT的建议-我需要在我的子域的每个子目录(将执行php代码并需要会话)中添加一个php.ini文件,并带有以下文本:

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

我希望这会有所帮助(花了我很长时间才弄清楚)。


这个很邪恶,现在调试了2个小时,因为会话共享在我的本地环境上运行良好。应该早点检查suhosin设置
weyandch 2014年


3

是。ini_set正在工作。但请记住销毁浏览器的所有缓存和cookie才能正常运行。

  1. 销毁浏览器的所有缓存和cookie
  2. xxx.example.com和中yyy.example.com,您的php文件应以这种方式启动。

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

0

我只是遇到了这个问题,事实证明我对两个不同的子域使用了不同的php.ini文件。这些ini文件指定了不同的session.save_path变量。出于显而易见的原因,对于需要共享会话的所有子域,这都必须相同。


0

尝试这个:

session_start(); 

$sessionId =  session_id();

登录用户。当用户将切换到其他子域时,发送的会话ID在URL中是这样的user.mydomain.com/?id=$sessionId

$sessionId =  $_GET['id'];

session_start($sessionId); 

现在,用户将获得所有会话值并保持登录状态。


6
如果您的答案以“尝试此操作”开头,则说明您做错了。
周杰伦·布兰查德

0

session_start()使用以下示例session_set_cookie_params().domain.com替换为您的域之前,请执行以下操作:

session_set_cookie_params(0, '/', '.domain.com');
session_start();

-3
if(isset($_COOKIE['session_id']))
    session_id($_COOKIE['session_id']);
    Zend_Session::start(); //or session_start();

    if(!isset($_COOKIE['session_id']))
        setcookie('session_id', session_id(), 0, '/', '.yourdomain.com');

这是一个很好的解决方案,但是您不能在所有情况下都使用它。例如,当您不能依赖非会话cookie时,它将不起作用。

如果正确使用,这实际上必须工作。

ini_set('session.cookie_domain', '.example.com' );

例如,您需要将其session_start()放在所有调用的文件之前以及session_start()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.