PHP實現跨網域名稱Cookie
來源:互聯網
上載者:User
cookie Cookie真是一個偉大的發明,它允許web開發人員保留他們的使用者的登入狀態。然而,當你的網站或網路
有一個以上的網域名稱時就會出現問題了。
在Cookie規範上說,一個cookie只能用於一個網域名稱,不能夠發給其它的網域名稱。因此,如果在瀏覽器中對
一個網域名稱設定了一個cookie,這個cookie對於其它的網域名稱將無效。如果你想讓你的使用者從你的網站中的其中
一個進行登入,同時也可以在其它網域名稱上進行登入,這可真是一個大難題。
我的解決方案將使用下面的一般架構:
一個預置的指令碼將用來接受通過GET或COOKIE方式傳遞過來的sessionid號。它將比COOKIE優先選擇GET
變數。所以,無論何時需要引用交叉的網域名稱時,我們把sessionid做為一個URL參數進行發送。
修改Apache配置,用來實現重寫所有的交叉網域名稱的cookie。這樣做的原因一會兒就會清楚了。
在任何時候出現一個交叉網域名稱引用時使用變數。
第一步:建立預置指令碼
將下面的代碼加到預置指令碼中(或出現在所有指令碼之前的函數中)。
<?php
/* 支援交叉網域名稱cookie... */
// 如果GET變數已經設定了,並且它與cookie變數不同
//則使用get變數(更新cookie)
global $HTTP_COOKIE_VARS, $HTTP_GET_VARS;
if (isset($sessionid) && isset($HTTP_GET_VARS[\'sessionid\']) && ($HTTP_COOKIE_VARS[\'sessionid\'] != $HTTP_GET_VARS[\'sessionid\'])) {
SetCookie(\'sessionid\', $HTTP_GET_VARS[\'sessionid\'], 0, \'/\', \'\');
$HTTP_COOKIE_VARS[\'sessionid\'] = $HTTP_GET_VARS[\'sessionid\'];
$sessionid = $HTTP_GET_VARS[\'sessionid\'];
}
?>
一旦這個代碼運行之後,一個全域的\'sessionid\'變數將可以用於指令碼。它將儲存著使用者的cookie中的
sessionid值,或者是通過GET請求發來的sessionid值。
第二步:為所有的交叉網域名稱引用使用變數
建立一個全域的設定檔,用於存放可以進行切換的網域名稱的基本引用形式。例如,如果我們擁有
domain1.com和domain2.com,則如下設定:
<?php
$domains[\'domain1\'] = "http://www.domain1.com/-$sessionid-";
$domains[\'domain2\'] = "http://www.domain2.com/-$sessionid-";
?>
現在,如果在代碼中如下做:
<?php
echo "Click <a href=\"", $domains[\'domain2\'], "/contact/?email=yes\">here</a> to contact us.";
?>
你將產生如下的輸出:
Click <a href="http://www.domain2.com/-66543afe6543asdf6asd-/contact/?email=yes\">here</a>
to contact us.
在這裡sessionid已經被插入到URL中去了。
在這個地方,你可能會想"這樣可能會在web伺服器上開啟名為橫線,sessionid,橫線的子目錄?!?!?"。
然而,下面的步驟將提供一個必需的戲法,以便讓它能夠使用!
第三步:配置Apache
現在,剩下的步驟就是配置apache來重寫這個URL:
http://www.domain2.com/-66543afe6543asdf6asd-/contact/
變成這樣:
http://www.domain2.com/contact/?sessionid=66543afe6543asdf6asd
並且這種url:
http://www.domain2.com/-66543afe6543asdf6asd-/contact/?email=yes
變成這樣:
http://www.domain2.com/contact/?email=yes&sessionid=66543afe6543asdf6asd
為了實現它,簡單地配置兩個虛擬伺服器,作為domain1和domain2,如下操作:
<VirtualHost ipaddress>
DocumentRoot /usr/local/www/domain1
ServerName www.domain1.com
RewriteEngine on
RewriteRule ^/-(.*)-(.*\?.*)$ $2&sessionid=$1 [L,R,QSA]
RewriteRule ^/-(.*)-(.*)$ $2?sessionid=$1 [L,R,QSA]
</VirtualHost>
<VirtualHost ipaddress>
DocumentRoot /usr/local/www/domain2
ServerName www.domain2.com
RewriteEngine on
RewriteRule ^/-(.*)-(.*\?.*)$ $2&sessionid=$1 [L,R,QSA]
RewriteRule ^/-(.*)-(.*)$ $2?sessionid=$1 [L,R,QSA]
</VirtualHost>
這些重寫的規則實現了上面兩個URL重寫的要求。
結論
通過使用變數結合與apache的重寫功能,交叉網域名稱cookie可以以一種簡單的方式實現。想要維護這樣的
系統,無論什麼時候連結交叉網域名稱,在使用網域名稱變數之外,什麼也不用作了!在網域名稱內部的連結不需要進行
修改,因為cookie會工作正常。
如果你有興趣看一下在生產網路中實際運作中的系統,請參觀http://www.familyhealth.com.au/。在
一些交叉網域名稱連結上移動你的滑鼠,並且看一下當你點擊後它們是如何被重寫的。
也許,使用這個技術唯一的問題就是無法刪除在使用者瀏覽器中的全部網域名稱下的cookie。