深入淺出剖析COOKIE與SESSION(基於PHP)
很多剛入門的小夥伴,可能對於cookie跟session都不會陌生,但是覺得這兩個東西很相似,但不知道該如何去區分跟使用,雖然兩者有很多相似之處,但是兩者又有不少區別,這裡給小夥伴們講解一下,供大家學習分享,少走彎路。轉帖請註明,侵刪。
共同點:session跟cookie都是伺服器用於持久化使用者資訊的工具。
不同點:二者的儲存方式和應用場景又有很大的不同
session:
session一般儲存在伺服器端,預設的情況下是以檔案儲存的方式進行儲存(配置:session.save_handler = ”files”),儲存路徑為session.save_path
這種方式相對比較安全,但是也相對比較侷限,待我慢慢道來
互動流程: 客戶端(瀏覽器)在第一次訪問伺服器端(網站)的時候,會通過請求頭,傳遞本地所儲存的cookie
其中有一個cookie為PHPSESSID ,這個cookie是用來跟伺服器進行互動的,相當於session讀取的一把鑰匙,伺服器接收到使用者請求頭傳遞過來的PHPSESSID,就會在session的儲存目錄中尋找對應的檔案,如果找到了,就讀取該文字,反序列化後放入到$_SESSION 超全域性變數中,在開啟session服務後,我們就可以通過這個變數檢視到我們儲存在服務端的資訊。
假如在這一次互動過程中,客戶端的請求頭中並沒有攜帶PHPSESSID這個cookie過來,那麼分兩種情況:
1 在這次互動中伺服器指令碼(例如PHP) 有開啟了session服務(session_start())的話, 服務端會生成一個PHPSESSID,在響應頭中傳送set-cookie請求,將該PHPSESSID儲存到客戶端,預設有效時間為瀏覽器開啟期間,此時該PHPSESSID儲存在記憶體中,關閉瀏覽器記憶體釋放(可以根據需要調整引數session.cookie_lifetime ,預設為0代表瀏覽器開啟期間 )
2 在互動中伺服器並沒有開啟session服務,那麼在這次互動中,不存在session的互動,也無法讀取$_SESSION變數
session的有效時間:
session的使用受限於兩個方面,一個是客戶端的PHPSESSID ,一個是服務端的儲存文字,只要其中一個失效,session就無法正常使用。這裡分兩個端討論:
1 受限於客戶端:
1 伺服器端對PHPSESSID在客戶端的儲存沒有做持久化,按照php的預設配置session.cookie_lifetime=0的話,如果使用者關閉瀏覽器,session失效。
2 伺服器端對PHPSESSID在客戶端的儲存已經做了持久化,那麼session.cookie_lifetime=N 那麼在有效期內,哪怕使用者關閉瀏覽器,下次還是可以訪問到session,因為session已經儲存到硬碟上而不是在記憶體中。只要伺服器端的儲存檔案還沒有失效,session就可以正常使用。
2 受限於服務端
session儲存在服務端不代表就一直可用,根據PHP的配置項 session.gc_maxlifetime = 1440 預設資源回收期限是1440S 過了這個有效期,該儲存檔案就被視為垃圾,無法通過PHPSESSID進行訪問。順帶提一句,session的資源回收,是通過配置引數設定回收概率去進行回收的,有興趣的同學可以自行百度。
總結:session並不適合用來做客戶端的持久化儲存,基於session儲存在服務端的特點,相對比較安全,但是持久化並不理想,session更適合用來作為使用者在某一場景下,短時間內對使用者重要資訊的暫時儲存。
cookie
持久化:cookie是儲存客戶端(記憶體或者硬碟),如果服務端向客戶端傳送設定cookie的請求時有帶上有效時間expire,那麼該cookie儲存在硬碟中,否則就存在記憶體中,關閉瀏覽器cookie消失。但是cookie有個優勢就是不用受到伺服器儲存檔案過期的影響,假如設定了過期時間,那麼在過期之前,cookie一直有效。
安全性:cookie基於儲存在客戶端的特點,並不需要像SESSION一樣讀取伺服器檔案,減少了伺服器的I/O開銷,但是在安全性方面很明顯不容樂觀,不能用於儲存重要的使用者資訊。
大小:一般的瀏覽器最多隻可以設定20個左右的cookie ,而session則沒有限制
互動方式:
cookie通過請求頭向服務端傳遞,服務端通過響應頭向客戶端傳遞cookie操作指令(增刪改)。在服務端直接改變$_COOKIE變數無法直接改變客戶端的cookie,只能通過cookie函式等去設定
在開啟session服務的前提下,session通過客戶端請求頭中的PHPSESSID獲取超全域性變數$_SESSION陣列,可以通過直接改變$_SESSION陣列的值,直接地改變session。
總結:一些對安全性要求不高,又為了方便需要在客戶端提前做好儲存的資訊,可以用cookie儲存在客戶端。
對於有叢集需求的小夥伴,由於有多臺伺服器,可以把session儲存在同一臺Redis伺服器中,實現session的歸集。
設定PHP配置檔案:php.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
這樣session的讀取跟設定都會在Redis中去進行。
好了,先到這裡,後續有更多的分享會進行更新,歡迎關注。