一直在使用session存儲數據,一直沒有好好總結一下session的使用方式以及其工作原理,今天在這裡做一下梳理。
這裡的介紹主要是基於php語言,其他的語言操作可能會有差別,但基本的原理不變。
session_start(); //使用該函數打開session功能
$_SESSION //使用預定義全局變量操作數據
unset($_SESSION['key']) //銷毀一個session的值
簡單地操作,一切都是由服務器實現;由於處理在後台,一切看起來也很安全。但是session采用什麼樣機制,又是怎樣被實現,並且如何來保持會話的狀態的呢?
浏覽器和服務器采用http無狀態的通訊,為了保持客戶端的狀態,使用session來達到這個目的。然而服務端是怎麼樣標示不同的客戶端或用戶呢?
這裡我們可以使用生活中的一個例子,假如你參加一個晚會,認識了很多人,你會采取什麼方式來區分不同的人呢!你可能根據臉型,也有可能根據用戶的名字,或者人的身份證,即采用一個獨一無二的標示。在session機制中,也采用了這樣的一個唯一的session_id來標示不同的用戶,不同的是:浏覽器每次請求都會帶上由服務器為它生成的session_id。
簡單介紹一下流程:當客戶端訪問服務器時,服務器根據需求設置session,將會話信息保存在服務器上,同時將標示session的session_id傳遞給客戶端浏覽器,浏覽器將這個session_id保存在內存中(還有其他的存儲方式,例如寫在url中),我們稱之為無過期時間的cookie。浏覽器關閉後,這個cookie就清掉了,它不會存在用戶的cookie臨時文件。以後浏覽器每次請求都會額外加上這個參數值,再服務器根據這個session_id,就能取得客戶端的數據狀態。
如果客戶端浏覽器意外關閉,服務器保存的session數據不是立即釋放,此時數據還會存在,只要我們知道那個session_id,就可以繼續通過請求獲得此session的信息。但是這個時候後台的session還存在,但是session的保存有一個過期時間,一旦超過規定時間沒有客戶端請求時,他就會清除這個session。
下面介紹一下session的存儲機制,默認的session是保存在files中,即以文件的方式保存session數據。在php中主要根據php.ini的配置session.save_handler來選擇保存session的方式。
這裡順便說明一下,如果要做服務器的lvs,即多台server的話,我們一般使用memcached的方式session,否則會導致一些請求找不到session。
一個簡單的memcache配置:
session.save_handler = memcache session.save_path = "tcp://10.28.41.84:10001"
當然如果一定要使用files文件緩存,我們可以將文件作nfs,將所有的保存session文件定位到一個地方。剛才講返回給用戶的session-id最終保存在內存中,這裡我們也可以設置參數將其保存在用戶的url中。
現有系統A, B; 假設A系統是可以獨立運行的web系統,即可以和浏覽器直接處理session, B系統是基於mobile的,需要調用A系統的功能接口,在保持A不改變的情況下,即登陸驗證,session存儲都不變的情況下,B系統能處理前端用戶的請求。
這裡提供的方案是使用PHP實現,在用戶登陸成功後,將保存的session的session-id返回給B系統,然後B系統每次請求其他接口都帶session_id。A系統在session_start前加上session_id(session_id);這樣B系統就能安全的調用A。