处理跨 Apache vhost 通配符域的 PHP 会话的最佳方法

处理跨 Apache vhost 通配符域的 PHP 会话的最佳方法

我目前正在运行一个允许用户使用自定义域的网站(即,他们可以使用 myaccount.com 而不是 mysite.com/myaccount)。他们只需更改其域的 A 记录,然后我们在 Apache 上使用通配符虚拟主机来捕获来自自定义域的请求。设置基本上如下所示。第一个虚拟主机捕获 mysite.com/myaccount 请求,第二个将用于 myaccount.com。如您所见,它们具有完全相同的路径和 php cookie_domain。

我注意到下面这一行周围有一些奇怪的行为"#The line below me"。当激活时,自定义域在每次页面加载时都会获得一个新的 session_id(与非自定义域会话不同)。但是,当我注释掉该行时,用户在每次页面加载时都会保留相同的 session_id,但该 session_id 与他们在非自定义域站点上看到的 session_id 不同,尽管它们完全位于同一台服务器上。

有一种“黑客”解决方法,涉及将用户重定向到 mysite.com/myaccount,获取会话 ID,重定向回 myaccount.com,然后在 myaccount.com 上使用该 ID。但这可能会变得有点混乱(即,如果用户退出 mysite.com/myaccount,myaccount.com 如何知道?)。

不管怎样,我正在使用数据库来管理会话(也就是说,在不同的服务器上没有问题,但是这无关紧要,因为我们目前只使用一台服务器来处理所有请求)。

我相当确定它与某种 CSRF 浏览器保护有关,但它难道不应该足够智能地知道它在同一台服务器上吗?

注意:这些是子域名,它们是完全独立的域名(但在同一台服务器上)。

<VirtualHost *:80>
    DocumentRoot "/opt/local/www/mysite.com"
    ServerName mysite.local
    ErrorLog "/opt/local/apache2/logs/mysite.com-error.log"
    CustomLog "/opt/local/apache2/logs/mysite.com-access.log" common
        <Directory "/opt/local/www/mysite.com">
                AllowOverride All
                #php_value session.save_path "/opt/local/www/mysite.com/sessions"
                php_value session.cookie_domain "mysite.local"
                php_value auto_prepend_file "/opt/local/www/mysite.com/core.php"
        </Directory>
</VirtualHost>

#Wildcard (custom domain) vhost
<VirtualHost *:80>
    DocumentRoot "/opt/local/www/mysite.com"
    ServerName default
    ServerAlias *
    ErrorLog "/opt/local/apache2/logs/mysite.com-error.log"
    CustomLog "/opt/local/apache2/logs/mysite.com-access.log" common
        <Directory "/opt/local/www/mysite.com">
                AllowOverride All
                #php_value session.save_path "/opt/local/www/mysite.com/sessions"
                # The line below me
                php_value session.cookie_domain "mysite.local"
                php_value auto_prepend_file "/opt/local/www/mysite.com/core.php"
        </Directory>
</VirtualHost>

答案1

通过在域之间传递 SID 肯定可以很容易地做到这一点?

关键是会话转移 - 如何执行取决于您。

要么通过使用 SID 的 GET,要么在应用程序级别。您有一个包含组合散列标识符(IP + UserAgent + OS 等)和相应 SID 的数据库表。然后您可以“检测”用户 - 匹配标识符并设置适当的会话。

但是,如果执行不正确,您最终可能会遭遇会话劫持或彻底丢失会话。

或者,更好的方法是使用第三方网站/服务进行身份验证(OpenID/Google/Facebook/Twitter 等)。然后您可以使用它来与相应的服务器端会话进行统计。

相关内容