1. 程式人生 > >HTTP無狀態協議和session原理(access_token原理)

HTTP無狀態協議和session原理(access_token原理)

無狀態協議是指協議對務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。 Http協議不像建立了socket連線的兩個終端,雙方是可以互相通訊的,http的客戶端只能通過請求伺服器來獲取相關內容或檔案資訊,具體內容可以通過我的另一篇文章瞭解。

http協議這種特性有優點也有缺點,優點在於解放了伺服器,每一次請求“點到為止”不會造成不必要連線佔用,缺點在於每次請求會傳輸大量重複的內容資訊。

客戶端與伺服器進行動態互動的Web應用程式出現之後,HTTP無狀態的特性嚴重阻礙了這些應用程式的實現,畢竟互動是需要承前啟後的,簡單的購物車程式也要知道使用者到底在之前選擇了什麼商品。於是,兩種用於保持HTTP連線狀態的技術就應運而生了,一個是Cookie,而另一個則是Session。HTTP本身是一個無狀態的連線協議,為了支援客戶端與伺服器之間的互動,我們就需要通過不同的技術為互動儲存狀態,而這些不同的技術就是Cookie和Session了。

先來說說Cookie:

Cookie的產生

Cookie最早是網景公司的前僱員Lou Montulli在1993年3月的發明。

Cookie是由伺服器端生成,傳送給User-Agent(一般是web瀏覽器),瀏覽器會將Cookie的key/value儲存到某個目錄下的文字檔案內,下次請求同一網站時就傳送該Cookie給伺服器(前提是瀏覽器設定為啟用Cookie)。Cookie名稱和值可以由伺服器端開發自己定義,對於JSP而言也可以直接寫入Sessionid,這樣伺服器可以知道該使用者是否合法使用者以及是否需要重新登入等。

Cookie用途

Cookies最典型的應用是判定註冊使用者是否已經登入網站,使用者可能會得到提示,是否在下一次進入此網站時保留使用者資訊以便簡化登入手續,這些都是Cookies的功用。另一個重要應用場合是“購物車”之類處理。使用者可能會在一段時間內在同一家網站的不同頁面中選擇不同的商品,這些資訊都會寫入Cookies,以便在最後付款時提取資訊。

Cookie生存週期

Cookie可以保持登入資訊到使用者下次與伺服器的會話,換句話說,下次訪問同一網站時,使用者會發現不必輸入使用者名稱和密碼就已經登入了(當然,不排除使用者手工刪除Cookie)。而還有一些Cookie在使用者退出會話的時候就被刪除了,這樣可以有效保護個人隱私。

Cookie在生成時就會被指定一個Expire值,這就是Cookie的生存週期,在這個週期內Cookie有效,超出週期Cookie就會被清除。有些頁面將Cookie的生存週期設定為“0”或負值,這樣在關閉頁面時,就馬上清除Cookie,不會記錄使用者資訊,更加安全。

Session:在計算機中,尤其是在網路應用中,稱為“會話”。

Session簡介

Session直接翻譯成中文比較困難,一般都譯成時域。在計算機專業術語中,Session是指一個終端使用者與互動系統進行通訊的時間間隔,通常指從註冊進入系統到登出退出系統之間所經過的時間以及如果需要的話,可能還有一定的操作空間。

具體到Web中的Session指的就是使用者在瀏覽某個網站時,從進入網站到瀏覽器關閉所經過的這段時間,也就是使用者瀏覽這個網站所花費的時間。因此從上述的定義中我們可以看到,Session實際上是一個特定的時間概念。

需要注意的是,一個Session的概念需要包括特定的客戶端,特定的伺服器端以及不中斷的操作時間。A使用者和C伺服器建立連線時所處的Session同B使用者和C伺服器建立連線時所處的Session是兩個不同的Session。

何時產生Session,怎樣產生Session?

當客戶端訪問伺服器時,伺服器根據需求設定Session,將會話資訊儲存在伺服器上,同時將標示Session的SessionId傳遞給客戶端瀏覽器,

瀏覽器將這個SessionId儲存在記憶體中,我們稱之為無過期時間的Cookie。瀏覽器關閉後,這個Cookie就會被清掉,它不會存在於使用者的Cookie臨時檔案。

以後瀏覽器每次請求都會額外加上這個引數值,伺服器會根據這個SessionId,就能取得客戶端的資料資訊。

如果客戶端瀏覽器意外關閉,伺服器儲存的Session資料不是立即釋放,此時資料還會存在,只要我們知道那個SessionId,就可以繼續通過請求獲得此Session的資訊,因為此時後臺的Session還存在,當然我們可以設定一個Session超時時間,一旦超過規定時間沒有客戶端請求時,伺服器就會清除對應SessionId的Session資訊。

綜上所述我們可以理解Session的建立流程是:

當用瀏覽器登入到某網站伺服器時,先找對應的Cookie檔案,當首次訪問是當然沒有Cookie檔案,所以在請求頭部中沒有Cookie的內容,即在請求頭部中沒有類似Cookie: JSESSIONID=XXXXXXXXXXXXXXX的內容,這時當請求到達伺服器後,伺服器看請求頭中沒有JSESSIONID值,於是生成一個Session物件,並由某種演算法產生一個值賦給這個Session的id,並將SessionId,和Session物件放入HashMap中,然後將這個SessionId發回以客戶端,即在響應的頭部有一行:Set-Cookie:JSESSIONID=XXXXXXXXXXXXXX,瀏覽器解析後會將在JSESSIONID和值記錄到Cookie中。

當用瀏覽器再次請求此網站的另一頁面時,瀏覽器檢檢視有沒有Cookie,這時有Cookie(前提是Cookie沒有過期),會自動的把Cookie的內容附加到請求頭中,即在請求頭附加了一行:Cookie: JSESSIONID=XXXXXXXXXXXXXXXXXXXXXXX,伺服器接收到請求後會根據JSESSIONID的值知道SessionId的值,在tomcat中兩個值是一樣的,然後你可根據這個SessionId找到對應的Session,可由Session中登入後設定的某些值是否為空,來判斷此使用者是否登入。

當用戶安全登出後(呼叫session.invalidate()),伺服器會將Session銷燬,並生成一個新的JSESSIONID發回用客戶端,瀏覽器接收響應後,會將Cookie中的JSESSIONID換成新值,當用戶再次訪問此伺服器時,會在請求中自動的加入新的JSESSIONID的值發到伺服器,這時伺服器根據JSESSIONID找不對應的Session了,因此就可知道是一次新的會話,伺服器會生成一個Session物件,並將客戶端發過來的JSESSION的值賦給這個Session的id。

如果客戶端禁用了Cookie那麼伺服器可就無法將session內容與客戶端對應上了。

Session以tomcat為例預設是儲存在記憶體中的,但是我們可以通過配置將Session持久化,儲存在硬碟檔案中