php cookie和session執行機制的理解

2021-09-26 06:35:07 字數 3721 閱讀 8194

由於http的無狀態性,設計了cookie機制,這樣可以識別出是否已經訪問過,可以針對性的做一些快取,減少伺服器壓力。

在http第一次訪問某**時,php會先判斷該客戶端是否是第一次訪問(是否有phpsessid),如果沒有那麼php設定該值並在響應報文的響應頭中以set_cookie返回,如果不是第一次訪問,那麼後面客戶端都會在請求頭將所有cookie以cookie為鍵帶到伺服器。

phpsessid無論session_start()是否開啟,第一次訪問都將建立。

在剛建立cookie時設定乙個cookie值,是無法在本次執行過程中獲得的,因為php還沒有以響應報文的形式將該cookie值帶到客戶端,當該cookie值到達客戶端並儲存後,在之後的程式中即可獲取該值。

然而在這麼多的cookie值中,有乙個特殊的cookie值就是phpsessid,這個值就是在php中用來維持session會話的(該值可在php配置檔案中進行更改),在到服務端時會檢測該值是否存在,如不存在則建立。

乙個網域名稱下的session的所有值都是儲存在伺服器端的乙個檔案中,且phpsessid的值是跟該檔案的名字一樣。

那麼問題來了,session會話是通過cookie值實現的,那如果cookie值被禁用掉session還能實現嗎?

這個是可以實現的,我們嘗試用以下幾種方法實現:

我們在火狐瀏覽器中把所有cookie全部阻止掉,這樣的話,伺服器端是可以在響應頭中設定cookie,可是瀏覽器並不接收,在請求頭中也不會帶有該**中的任何cookie。在實驗前如果php.ini中session.auto_start該值設為0。

在沒有cookie之後,http將無法識別客戶端是否訪問過,每一次的訪問都會被視為第一次訪問,phpsessid的值不斷改變,儲存session的檔案也不斷增加。導致你無法獲取上一次你所設下的session值。也就是伺服器端已經不認識你了。如果我們仍要保持該session會話,那我們必須向伺服器端傳遞乙個固定的phpsessid,因為該值會被作為檔案儲存在伺服器上。如果該值一定之後,那麼我們每次都是在那個檔案裡取值。請求頭上面已不能傳遞cookie值,但是我們可以從http請求包中的其他方法傳遞(請求路徑上,請求主體中),也就是我們經常所說的get或者post方式傳遞乙個phpsessid值。

1.路徑為通過get方式傳遞上去(這是我自己的本地網域名稱)

session_id($_get['phpsessid']);

session_start();

//$_session['name'] = 'hello';

echo $_session['name'];

這是php**,這是通過session_id(一定要放在session_start之前)函式實現的,這樣以後每一次傳遞都帶上phpsessid=yzlcxh那麼就能維持該session會話了

也可以通過post方式,在表單提交時增加隱藏框,把該值傳遞上去,也能做到同樣的效果,推薦用post方式吧(更安全,別人也看不出來你在幹什麼)。

2.第二種方法是想用ajax(jquery的一種非同步請求)在前端發起請求的時候,設定請求頭cookie:phpsessid=yzlcxh。不過這個方法失敗了,refused to set unsafe header "cookie",規定不能手動設定請求頭cookie,所以暫時只想到了第一種方法是可以實現的。

在理解了session的執行機制之後,我們可以考慮實現一下session共享。

如果你的**是存放在乙個機器上,那麼是不存在這個問題的,因為會話資料就在這台機器,但是如果你使用了負載均衡把請求分發到不同的機器呢?這個時候會話id在客戶端是沒有問題的,但是如果使用者的兩次請求到了兩台不同的機器,而它的session資料可能存在其中一台機器,這個時候就會出現取不到session資料的情況,於是session的共享就成了乙個問題。

1. 基於nfs的session共享

nfs是net filesystem的簡稱,最早由sun公司為解決unix網路主機間的目錄共享而研發。

這個方案實現最為簡單,無需做過多的二次開發,僅需將共享目錄伺服器mount到各頻道伺服器的本地session目錄即可,缺點是nfs依託 於復 雜的安全機制和檔案系統,因此併發效率不高,尤其對於session這類高併發讀寫的小檔案, 會由於共享目錄伺服器的io-wait過高,最終拖累前端web應用程式的執行效率。

2. 基於資料庫的session共享

首選當然是大名鼎鼎的mysql資料庫,並且建議使用記憶體表heap,提高session操作的讀寫效率。這個方案的實用性比較強,相信大家普 遍在 使用,它的缺點在於session的併發讀寫能力取決於mysql資料庫的效能,同時需要自己實現session淘汰邏輯,以便定時從資料表中更新、刪除 session記錄,當併發過高時容易出現表鎖,雖然我們可以選擇行級鎖的表引擎,但不得不否認使用資料庫儲存session還是有些殺雞用牛刀的架勢。

3. 基於cookie的session共享

這個方案我們可能比較陌生,但它在大型**中還是比較普遍被使用。原理是將全站使用者的session資訊加密、序列化後以cookie的方式, 統一 種植在根網域名稱下(如:.host.com),利用瀏覽器訪問該根網域名稱下的所有二級網域名稱站點時,會傳遞與之網域名稱對應的所有cookie內容的特性,從而實現 使用者的cookie化session 在多服務間的共享訪問。

這個方案的優點無需額外的伺服器資源;缺點是由於受http協議頭信心長度的限制,僅能夠儲存小部分的使用者資訊,同時cookie化的 session內容需要進行安全加解密(如:採用des、rsa等進行明文加解密;再由md5、sha-1等演算法進行防偽認證),另外它也會占用一定的帶 寬資源,因為瀏覽器會在請求當前網域名稱下任何資源時將本地cookie附加在http頭中傳遞到伺服器。

4. 基於memcache的session共享

memcache由於是一款基於libevent多路非同步i/o技術的記憶體共享系統,簡單的key + value資料儲存模式使得**邏輯小巧高效,因此在併發處理能力上佔據了絕對優勢,目前本人所經歷的專案達到2000/秒 平均查詢,並且伺服器cpu消耗依然不到10%。

另外值得一提的是memcache的記憶體hash表所特有的expires資料過期淘汰機制,正好和session的過期機制不謀而合,降低了 過期session資料刪除的**複雜度,對比「基於資料庫的儲存方案」,僅這塊邏輯就給資料表產生巨大的查詢壓力。

最後就是session和cookie的區別:

1.存放的位置

cookie儲存在客戶端,session一般儲存在伺服器端的檔案系統或資料庫或mamcache

2.安全性

由於session存放在伺服器端,cookie存在於客戶端可以直接在瀏覽器上查到並更改,所以cookie的安全性較session弱

3.網路傳輸量

cookie需通過網路實現客戶端與伺服器端之間的傳輸,而session儲存在伺服器端,無需傳輸

4.生存時間(以設定24分鐘為例)

(1)cookie的生命週期是累計的。從建立的時候就開始計時,24分鐘後cookie生命週期結束,cookie自動失效

(2)session的生命週期是間隔的,從建立時開始計時,比如在24分鐘內(php.ini預設session的失效時間就是1440s,即24m)沒有訪問過session(指沒有執行含session的檔案),那麼session資訊就自動無效,但如果在24分鐘之內,比如第23分鐘訪問過session,那麼它的生命週期將重新開始計算。

5.所儲存內容的大小

cookie實在客戶端鍵值方式儲存的,資料量有所限制,但是session在服務端用文字儲存是可以無限量的。

php,cookie和session和序列化

網路流量分析和網路故障處理工具。關於這一款網路分析工具的使用我們會在後續的文章中進行講述和演示。servertokens os 通常將可以用自定義的引數值替換原有變數值的情況稱為變數覆蓋漏洞。經常導致變數覆蓋漏洞場景有 使用不當,extract 函式使用不當,parse str 函式使用不當,imp...

javaweb中Cookie和Session實現

cookie是存在於瀏覽器的文字,用於儲存使用者的登入密碼等資料 session存在於服務端,用於跟蹤使用者登入狀態等 cookie cookies request.getcookies if cookies null cookies.length 0 else 在servelt中通過respons...

Servlet中Cookie和Session的學習

會話cookie 關閉瀏覽器,就失效 持久cookie 存放在客戶端上。在指定的期限內有效。是以檔案形式存放的 setmaxage 應用 自動登入 瀏覽記錄 購物車 http的請求是無狀態。客戶端與伺服器在通訊的時候,是無狀態的,其實就是客戶端在第二次來訪的時候,伺服器根本就不知道這個客戶端以前有沒...