程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> PHP中session跨子域的三種實現方法

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

編輯:PHP綜合

在之前做東西的時候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.com
session.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實現跨子域的幾種解決方案,希望能幫助到有需要的大家。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved