【问题标题】:Changing symlink destroys PHP session更改符号链接会破坏 PHP 会话
【发布时间】:2011-04-16 03:36:06
【问题描述】:

我在 Apache 上运行 PHP/Yii 应用程序。我尝试过以下操作:

  1. 我的 DocumentRoot 是“www”,它是一个符号链接。符号链接指向 /usr/local/src/releases/mysite-1/www
  2. 我将 /usr/local/src/releases/mysite-1/www 目录重命名为 /usr/local/src/releases/mysite-2/www
  3. 我使用以下命令删除旧的 www 符号链接:rm -f www
  4. 我使用以下命令创建一个新符号链接:ln -s /usr/local/src/releases/mysite-2/www www

这样做会导致 PHP 会话被破坏,甚至无需重新启动 Apache。有任何想法吗?我检查了我的 PHP save_path,这应该不是问题,因为我使用 Redis 进行会话处理。我的 Apache 配置如下所示:

DocumentRoot "www"
<Directory "www">
   Options -Indexes +FollowSymLinks
   RewriteEngine on
   # if a directory or a file exists, use it directly 
   RewriteCond %{REQUEST_FILENAME} !-f 
   RewriteCond %{REQUEST_FILENAME} !-d 
   # otherwise forward it to index.php 
   RewriteRule . index.php 
   ...

编辑: 我怀疑问题出在 Yii 上。经过一些进一步的测试,看起来会话数据实际上并没有被破坏。我已经切换到基于文件的会话。这是我所看到的:

  1. 用户登录,会话 id 设置为 tdv3l6jgf2sb1dnutt7updhfo1

  2. 会话数据如下:

    数组(5){ ["20b30da82f6dcc260a66f6a1044a5c3a_id"]=> 字符串(1) "2" ["20b30da82f6dcc260a66f6a1044a5c3a_name"]=> 字符串(8) "ewest fb" [“20b30da82f6dcc260a66f6a1044a5c3afbId”]=> 字符串(10)“1028251971” [“20b30da82f6dcc260a66f6a1044a5c3aisFbUser”]=>布尔(真) [“20b30da82f6dcc260a66f6a1044a5c3a__states”]=>数组(3){ ["fbId"]=> bool(true) ["isFbUser"]=> bool(true) ["avatar"]=> bool(true) } }

  3. 会话文件在/tmp下创建

  4. 如上所述,我更改了 www 符号链接。会话 id 保持不变,会话数据完好无损!但是 Yii::app()->user->isGuest 的评估结果为真。所以会话数据仍然存在,但 Yii 认为我已经退出了!

Yii 是否有另一个位置写入用户数据? state.bin 文件位于 www 之外的运行时目录中。

【问题讨论】:

  • 乍一看,我不明白这是怎么回事,但是在步骤 2 和 3 之后会话是否仍然出现在 Redis 中?
  • 我认为所有这些都与启用 allowAutoLogin 有关。更改符号链接会导致 Yii 使用的 cookie id 丢失。但它不会导致 PHP 会话丢失。
  • 对于已经登陆这里的其他人,我们在更改每个构建的文档根目录(而不是使用符号链接)时遇到了类似的丢失会话的问题。原因是 suhosin.session.cryptdocroot 标志导致会话加密密钥依赖于 Documentroot 字段

标签: php apache yii


【解决方案1】:

我无法找出导致问题的原因,但我确实想出了一个解决方法。

代替:

  1. 将 www 符号链接更改为 d-xxx,其中 xxx 是发布版本

我现在:

  1. 将旧版本目录“d”移动到 d-yyy,其中 yyy 是旧版本版本
  2. 将新版本提取到“d”
  3. “www”符号链接仍然指向“d”

所以“www”符号链接的真实路径永远不会改变。这解决了这个问题,我不知道为什么会这样。与此同时,我手动设置了 Yii 的 securityManager 的validationKey 和encryptionKey。

此时我唯一怀疑的是 APC 和我的设置出了点问题。

【讨论】:

    【解决方案2】:

    Yii 1.x 中有奇怪的代码: СApplication.php

    public function getId()
    {
        if($this->_id!==null)
            return $this->_id;
        else
            return $this->_id=sprintf('%x',crc32($this->getBasePath().$this->name));
    }
    

    因此,您只需在应用程序配置文件中设置应用程序 ID。

    例如,protected/config/web.php

    return  [
             'id'=>'my application'
    

    ...

    【讨论】:

      猜你喜欢
      • 2013-11-10
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 2013-10-31
      • 2010-10-05
      • 2016-04-30
      • 2015-12-09
      • 1970-01-01
      相关资源
      最近更新 更多