PHP網路技術(六)——session及與cookie的比較
PHP網路技術(六)
——session及與cookie的比較
(原創內容,轉載請註明來源,謝謝)
一、概念
session是持續的、雙向性的連線。其是通過在cookie中儲存sessionID,實現session的傳遞,以區分不同使用者的session。
與cookie的儲存方式不同,session儲存在服務端,每個session一個檔案進行儲存。通過上述的sessionID,可以獲取不同的session檔案。session檔名是sess_32位隨機字串,裡面的內容形如:變數名|型別:長度:值。
PHP在使用session之前,需要有session_start()命令。
二、原理
由於HTTP不支援服務端儲存客戶端的資訊,因此引入session的概念。
session通過一個稱為PHPSESSID的cookie和伺服器聯絡,其通過sessionID判斷客戶端的使用者,即session的檔名。因此,通常情況下,使用session前提是瀏覽器支援且啟用cookie(瀏覽器不支援的情況下也可以使用,具體實現方式下面會提到)。
session實際上是在客戶端和伺服器之間通過HTTP Request和HTTP Response進行互傳,其中sessionID按照特定的演算法生成,包含在HTTP Request裡面,具有唯一性和隨機性。
和cookie一樣,如果沒有設定失效時間,瀏覽器關閉後session檔案自動登出,當重新請求時會重新註冊一個sessionID。當客戶端沒有禁用cookie,cookie會在啟用session會話時儲存sessionID及其生命週期,也可以通過cookie設定session的生命週期。方法如下:
setcookie(session_name(),session_id(), time()+3600, ‘/’, ‘127.0.0.1’, false, true)
設定了session過期方式,則在過期後由瀏覽器進行回收,如果未過期,則瀏覽器關閉後再開啟仍有效。
三、瀏覽器禁用cookie時的處理方式
預設情況下,由cookie儲存sessionID,並且自動傳送給服務端,服務端由此進行判斷sessionID並且取出相應的session檔案。但是,如果瀏覽器禁止了session,則無法通過cookie獲取sessionID,則需要另闢蹊徑。
常用的做法是通過URL將sessionID從客戶端傳遞給服務端,服務端採用get的方式獲取並從服務端本地獲取相應sessionID對應的session檔案。如果沒有則獲取失敗。
程式碼如下;
客戶端:client.php
$sessionName= session_name();
$sessionID= session_id();
echo‘<a href=”server.php?’.$sessionName.’=’.$sessionID.’”>跳轉</a>’;
服務端: server.php
$sessionName= session_name();
$sessionID= $_GET[$sessionName];
session_id($sessionID);
session_start();
四、session儲存
當有大量的session進行操作時,則對session進行儲存並取出的效率更高。通常的做法是實現PHP的介面session_set_save_handler(callback open, callback close, callbackread, callback write, callback destroy, callback gc)。
另外,由於在關係型資料庫中儲存效率較低,建議採用非關係型資料庫或快取進行儲存,如memcache或redis,效率會更高。
五、關於cookie與session
1)儲存位置
cookie資料存放在客戶的瀏覽器上,session資料放在伺服器上,但是sessionID作為一個cookie儲存在客戶端(除非客戶端禁用cookie,則需要使用上述url傳參的方式實現)。
2)安全性
session相對cookie來說安全,但是cookie和session的安全性差距不大,因為cookie和session是通過sessionID繫結的,因此獲取到cookie後,傳送給伺服器,伺服器通過cookie就會進行驗證。因此,安全性主要還是需要在程式碼中進行實現。
另外,為了防止cookie劫持(將其他人的電腦裡的cookie複製到自己的電腦,使自己有其他人電腦的cookie,進而進行相應的操作),下需要在cookie中加入IP、UA等特殊資訊,並在伺服器進行比對。
3)跨軟體
由於cookie是不同的客戶端各自儲存,因此不同的瀏覽器無法共用cookie。而session由於是儲存在伺服器,因此不受軟體影響。但是由於sessionID是儲存在cookie中的,因此通常情況下跨瀏覽器也無法正確讀取到session。
4)資源佔用
cookie在每次HTTP請求中都會發出,無論是客戶端還是服務端,因此cookie主要是佔用頻寬。session是儲存在服務端,並不進行傳輸,因此不佔頻寬,但是由於儲存在服務端,因此佔用服務端的儲存並且讀寫session佔用服務端的IO。
因此,高併發情況下,服務端需要同時讀取多個session檔案,對服務端造成壓力較大,cookie存在的問題則是佔用頻寬較多。
因此減輕伺服器效能方面需要使用cookie,減少網路壓力使用session。
5)限制條件
每個cookie儲存的資料不能超過4kb,且一般瀏覽器對每個域名下的cookie還有數量的限制,另外瀏覽器也可以設定禁止cookie。就此方面來說,session不受限制。
6)使用場景
通常情況下,cookie用於安全性不那麼高的地方,如記住使用者名稱。並且可以在使用cookie時通過判斷IP、UA或其他加密資訊進行校驗,防止cookie劫持。要儲存使用者名稱也可以將使用者名稱通過md1等不可逆演算法加鹽或者其他方式進行加密,並且後臺再次進行判斷,達到儲存密碼的功能。
驗證登陸的功能通常用session實現。即在登陸頁面驗證成功後,將內容寫入session。並且,為了在後面的每個頁面都進行判斷,當判斷成功時,會再次重設session的時間;當驗證失敗或者超時導致session登出,則跳轉到登陸頁。這就是實現超時沒有操作需要重新登陸的原理。在mvc或其他單一入口的方式下,通常會將驗證session和重設時間的方法寫在basecontroller(基類),其他檔案繼承該類進行驗證session資訊與重置session過期時間。
——written by linhxx 2017.07.24