PHP中session跨子域的三種實現方法_php技巧

來源:互聯網
上載者:User

在之前做東西的時候session一般就直接存在資料庫中這樣就能解決跨域不僅僅是跨子域,但是今天遇到這個問題是,自己要在別人現有的東西上面做修改。由於僅僅是子域當時就想肯定有簡單的解決方案,度娘了找到了三種解決辦法:

Session主要分兩部分:

一個是Session資料,該資料預設情況下是存放在伺服器的tmp檔案下的,是以檔案形式存在。

另一個是標誌著Session資料的Session Id,Session ID,就是那個 Session 檔案的檔案名稱,Session ID 是隨機產生的,因此能保證唯一性和隨機性,確保 Session 的安全。一般如果沒有設定 Session 的生存周期,則 Session ID 儲存在記憶體中,關閉瀏覽器後該 ID 自動登出,重新請求該頁面後,重新註冊一個 session ID。如果用戶端沒有禁用 Cookie,則 Cookie 在啟動 Session 會話的時候扮演的是儲存 Session ID Session 生存期的角色。

兩個不同的網域名稱網站,想用同一個Session,就是牽扯到Session跨域問題!

預設情況下,各個伺服器會各自分別對同一個用戶端產生 SESSIONID,如對於同一個使用者瀏覽器,A 伺服器產生的 SESSION ID 是 11111111111,而B 伺服器產生的則是222222。另外,PHP 的 SESSION資料都是分別儲存在本伺服器的檔案系統中。想要共用 SESSION 資料,那就必須實現兩個目標:

一個是各個伺服器對同一個用戶端產生的SESSION ID 必須相同,並且可通過同一個 COOKIE 進行傳遞,也就是說各個伺服器必須可以讀取同一個名為 PHPSESSID 的COOKIE;

另一個是 SESSION 資料的儲存方式/位置必須保證各個伺服器都能夠訪問到。這兩個目標簡單地說就是多伺服器(A、B伺服器)共用用戶端的 SESSION ID,同時還必須共用伺服器端的 SESSION 資料。

有三種解決方案:

1.只要在php頁面的最開始(要在任何輸出之前,並且在session_start()之前)的地方進行以下設定

ini_set('session.cookie_path', '/');ini_set('session.cookie_domain', '.mydomain.com');ini_set('session.cookie_lifetime', '1800');

2.在php.ini裡設定

session.cookie_path = /session.cookie_domain = .mydomain.comsession.cookie_lifetime = 1800

3.在php頁面最開始的地方(條件同1)調用函數

session_set_cookie_params(1800 , '/', '.mydomain.com');

session 有個Session_id 作為session的惟一標誌。

要實現Session子域,實際上是在同一個瀏覽器中在訪問兩個A 和B子域時,其session是相同的。

由於session都是儲存在伺服器端,如何讓兩台伺服器識別這兩個請求是由一個瀏覽器發出的呢?

Cookie是儲存在用戶端的,伺服器通常通過Cookie來識別不同的用戶端,因此,可以使用Cookie來儲存Session_id, 並將該Cookie設定為父域。

例如,當訪問a.sso.com 時,就將session_id 儲存在Cookie中。當訪問b.sso.com時,則將session_id  從Cookie中取出來,

並通過session_id 去某個持久化容器中擷取Session。

例如,當訪問a.sso.com 時,就將session_id 儲存在Cookie中。當訪問b.sso.com時,則將session_id  從Cookie中取出來,

並通過session_id 去某個持久化容器中擷取Session。

在本實驗中,使用PHP來作為實驗語言。

當訪問a.sso.com時,則將通過
 

session_start(); $_SESSION['person'] = "SBSBSBS"; $session_id = session_id(); setcookie('name',$session_id,time()+3600*24,'/','SSO.com');

  將session_id 儲存在cookie中。

由於在PHP中,session是一個數組,PHP有 serialize() 函數,將數組序列化

$session_value = serialize($_SESSION);

然後將$session_value 儲存在資料庫中。

在訪問b.sso.com時,則從cookie中擷取到session_id,然後到資料庫中根據session_id將 經過序列化過的session 擷取出來

接著就可以對該session進行操作,實現session 跨子域。

由於將session儲存在資料庫中,存取都是比較費時的操作,因此可以將session儲存在緩衝中,例如memcached 或者redis中,

這樣對session的存取操作就比較快速了。

使用緩衝還有個好處就是,通常session有一定得存活時間,如果存在資料庫中,還需要儲存該session的存活時間,在取出session時,還需要判斷其是否失效。

使用緩衝存放session就可以在存放的時候設定其存活時間,減少了取出後的失效判斷這一個過程。

我的解決方案是在入口出添加如下代碼:

ini_set('session.cookie_path', '/'); ini_set('session.cookie_domain', '.jb51.net'); //注意jb51.net換成你自己的網域名稱ini_set('session.cookie_lifetime', '1800');

如圖:

網站一

網站二

 

可以看到兩個網站的PHPSESSID是一樣的,當然也解決了跨子網域名稱的問題了

以上就是在PHP中session實現跨子域的幾種解決方案,希望能協助到有需要的大家。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.