程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP基礎知識 >> php session實現原理

php session實現原理

編輯:PHP基礎知識
 

SESSION的實現中采用COOKIE技術,SESSION會在客戶端保存一個包含session_id(SESSION編號)的COOKIE;在服務器端保存其他session變量,比如session_name等等。當用戶請求服務器時也把session_id一起發送到服務器,通過 session_id提取所保存在服務器端的變量,就能識別用戶是誰了。同時也不難理解為什麼SESSION有時會失效了。

  當客戶端禁用COOKIE時(點擊IE中的“工具”?“Internet選項”,在彈出的對話框裡點擊“安全”?“自定義級別”項,將“允許每個對話 COOKIE”設為禁用),session_id將無法傳遞,此時SESSION失效。不過php5在linux/unix平台可以自動檢查cookie 狀態,如果客戶端設置了禁用,則系統自動把session_id附加到url上傳遞。windows主機則無此。


php session原理2007-08-17 13:24眾所周知,http協議是一個無狀態協議,簡單來說就是,web服務器是不知道現在連接上來的人到底是哪個人,為了滿足選擇性發送信息的需求,在http的基礎上做了很多擴展來達到這個目的,如數字簽名、cookie、session等。
web服務器或者web程序如何能夠知道現在連接上來的是誰?要解決這個問題,首先需要在服務器端和客戶端建立一一對應關系,下邊我通過抓取http的內容來說明這種對應關系是如何建立的。
我使用的是一個叫做httplook的http包嗅探工具,然後在本地web服務器的根目錄下建立一個叫test.php的文件,地址是:http://localhost/test.php,一切就緒以後我通過浏覽器反復打開這個頁面。

<?php
session_start();
if (isset($_SESSION['test_sess'])){
$_SESSION['test_sess']++;
}else{
$_SESSION['test_sess'] = 0;
}
echo $_SESSION['test_sess'];
?>;


以下是前兩次向服務器發出的信息及服務器返回的信息
引用:原帖由 "第一次請求服務器" 發表:

GET /test.php HTTP/1.1
Accept: */*
Referer: http://localhost/
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)
Host: localhost
Connection: Keep-Alive


引用:原帖由 "服務器第一次返回" 發表:

HTTP/1.1 200 OK
Date: Fri, 26 Aug 2005 07:44:22 GMT
Server: Apache/2.0.54 (Win32) SVN/1.2.1 PHP/5.0.4 DAV/2
X-Powered-By: PHP/5.0.4
Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 1
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Content-Language: Off


引用:原帖由 "第二次請求服務器" 發表:

GET /test.php HTTP/1.1
Accept: */*
Referer: http://localhost/
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)
Host: localhost
Connection: Keep-Alive
Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3


引用:原帖由 "服務器第二次返回" 發表:

HTTP/1.1 200 OK
Date: Fri, 26 Aug 2005 07:44:23 GMT
Server: Apache/2.0.54 (Win32) SVN/1.2.1 PHP/5.0.4 DAV/2
X-Powered-By: PHP/5.0.4
Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 1
Keep-Alive: timeout=15, max=98
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Content-Language: Off

 

仔細對比這些輸出,第二次請求比第一次請求多出來的就是:
Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3
這個header將會向服務器發送一個cookie信息,告訴服務器我有一個cookie,名字叫PHPSESSID,內容是bmmc3mfc94ncdr15ujitjogma3。
這個cookie是怎麼來的呢?看第一次服務器返回的信息裡邊有:
Set-Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3; path=/
這是服務器向客戶端浏覽器寫一個cookie,名字是PHPSESSID,值是bmmc3mfc94ncdr15ujitjogma3,這個值實際就是所謂的session_id。
繼續看第二次向服務器發出的請求,仍然向服務器發送了PHPSESSID這個cookie

可以得到以下結論:
1、只要使用了session,就會通過cookie的方式向客戶端浏覽器發送session
2、每次向服務器發出請求的時候,本地浏覽器會把cookie附帶在請求信息中

說到這裡,服務器端和客戶端如何通過session做到一一對應的答案就很清楚了,明白了這個道理,對於使用session有很大幫助,請細細體會。

 

--------------------------------------------------------------------------------
Yarco 回復於:2005-08-31 18:09:05

奇怪...好帖居然沒人頂...

請教斑竹.
假如我第二次發送請求不寫:
Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3
是不是意味著服務器端會調用:
$_SESSION['test_sess'] = 0;
這個呢?

ps,居然發現一個變量$_SERVER["HTTP_COOKIE"], 沒看到手冊裡有寫.

ps,斑竹有沒在win32下好的協議分析工具?

and ps...
實際上我是在翻前幾天看到一位兄弟說是關於php5出錯不顯示錯誤的問題.
我也遇到了...error_reporting已經設置了E_ALL. 我亂寫一通, 居然沒反應.
版本php5.0.4
是不是各位普遍有這種情況?


--------------------------------------------------------------------------------
夜貓子 回復於:2005-08-31 18:53:30

>;假如我第二次發送請求不寫:
>;Cookie: PHPSESSID=bmmc3mfc94ncdr15ujitjogma3
isset($_SESSION['test_sess'])就會返回false,結果就是
$_SESSION['test_sess'] = 0;
你的想法是正確的

如果是分析一下http協議的話,telnet 80就可以了,稍微好點就用http look一類的東西,最好的工具是sniffer pro。


--------------------------------------------------------------------------------
hightman 回復於:2005-08-31 20:03:39

哎,都是基於cookie所以特別不安全.

只要這個session_id被知曉或者說cookie內容被盜(這很容易辦到), 就很有可能被盜竊身份.

我在作程序時session數據都加入了IP驗證. 非根本性的解決方案.


--------------------------------------------------------------------------------
Yarco 回復於:2005-08-31 20:22:22

你這樣一說, 我倒是有問題出來了.
cookie被盜, 我相信是指這些情況吧:
1. 就是有n天效果的那種.
2. 被hack或者攔截了

假如不考慮上面因素
按理說那個session_id是個臨時值...也按理說臨時值對應所儲存在服務器端裡的文件也是臨時的, 用完之後應該被刪掉的...
所以再要盜竊身份的話, 是不是說就得找到那個當前在服務器上存在的那個對應的session_id呢?


--------------------------------------------------------------------------------
hightman 回復於:2005-08-31 22:19:56

像論壇上的貼圖有些[IMG]標簽沒過濾好,cookie很容易被獲取.


--------------------------------------------------------------------------------
夜貓子 回復於:2005-08-31 22:30z:11

session_id的洩露最大的可能是嗅探,如果你處於廣播型的以太網內就可以被嗅探

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