|
https:///post/5de4c3c76fb9a071b86cc482#heading-0
前言無狀態(tài)的HTTP協(xié)議很久很久之前, Web基本都是文檔的瀏覽而已。既然是瀏覽, 作為服務(wù)器, 不需要記錄在某一段時間里都瀏覽了什么文檔, 每次請求都是一個新的HTTP協(xié)議,就是請求加響應(yīng)。不用記錄誰剛剛發(fā)了HTTP請求, 每次請求都是全新的。 如何管理會話隨著交互式Web應(yīng)用的興起, 像在線購物網(wǎng)站,需要登錄的網(wǎng)站等,馬上面臨一個問題,就是要管理回話,記住那些人登錄過系統(tǒng),哪些人往自己的購物車中放商品,也就是說我必須把每個人區(qū)分開。 本文主要講解cookie,session, token 這三種是如何管理會話的; cookiecookie 是一個非常具體的東西,指的就是瀏覽器里面能永久存儲的一種數(shù)據(jù)。跟服務(wù)器沒啥關(guān)系,僅僅是瀏覽器實現(xiàn)的一種數(shù)據(jù)存儲功能。 cookie由服務(wù)器生成,發(fā)送給瀏覽器,瀏覽器把cookie以KV形式存儲到某個目錄下的文本文件中,下一次請求同一網(wǎng)站時會把該cookie發(fā)送給服務(wù)器。由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用,同時不會占據(jù)太多磁盤空間。所以每個域的cookie數(shù)量是有限制的。 如何設(shè)置客戶端設(shè)置
服務(wù)端設(shè)置不管你是請求一個資源文件(如html/js/css/圖片), 還是發(fā)送一個ajax請求, 服務(wù)端都會返回response.而response header中有一項叫
Cookie,SessionStorage,LocalStorageHTML5提供了兩種本地存儲的方式 sessionStorage 和 localStorage;
session什么是sessionsession從字面上講,就是會話。這個就類似你和一個人交談,你怎么知道當時和你交談的是張三而不是李四呢?對方肯定有某種特征(長相等)表明他是張三; session也是類似的道理,服務(wù)器要知道當前請求發(fā)給自己的是誰。為了做這種區(qū)分,服務(wù)器就是要給每個客戶端分配不同的"身份標識",然后客戶端每次向服務(wù)器發(fā)請求的時候,都帶上這個”身份標識“,服務(wù)器就知道這個請求來自與誰了。 至于客戶端怎么保存這個”身份標識“,可以有很多方式,對于瀏覽器客戶端,大家都采用cookie的方式。 過程(服務(wù)端session + 客戶端 sessionId)
存在的問題擴展性不好單機當然沒問題, 如果是服務(wù)器集群, 或者是跨域的服務(wù)導(dǎo)向架構(gòu), 這就要求session數(shù)據(jù)共享,每臺服務(wù)器都能夠讀取session。 舉例來說, A網(wǎng)站和B網(wǎng)站是同一家公司的關(guān)聯(lián)服務(wù)?,F(xiàn)在要求,用戶只要在其中一個網(wǎng)站登錄,再訪問另一個網(wǎng)站就會自動登錄,請問怎么實現(xiàn)?這個問題就是如何實現(xiàn)單點登錄的問題
另一種方案是服務(wù)器索性不保存session數(shù)據(jù)了,所有數(shù)據(jù)就保存在客戶端,每次請求都發(fā)回服務(wù)器。這種方案就是接下來要介紹的基于Token的驗證; Token過程
這個方式的技術(shù)其實很早就已經(jīng)有很多實現(xiàn)了,而且還有現(xiàn)成的標準可用,這個標準就是JWT; JWT(JSON Web Token)數(shù)據(jù)結(jié)構(gòu)實際的JWT大概就像下面這樣:
JSON Web Tokens由dot(.)分隔的三個部分組成,它們是:
因此,JWT通常如下展示: xxxxx.yyyyy.zzzz Header(頭部)Header 是一個 JSON 對象
Payload(負載)Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的數(shù)據(jù)
JWT 默認是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個部分。 Signature(簽名)Signature 是對前兩部分的簽名,防止數(shù)據(jù)被篡改。 首先,需要指定一個密鑰(secret)。這個密鑰只有服務(wù)器才知道,不能泄露給用戶。然后,使用Header里面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產(chǎn)生簽名。
算出簽名后,把 Header、Payload、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.)分隔,就可以返回給用戶。
使用方式客戶端收到服務(wù)器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。此后,客戶端每次與服務(wù)端通信,都要帶上這個JWT。你可以把它放在Cookie里面自動發(fā)送,但是這樣不能跨域,所以更好的做法是放在HTTP請求的頭信息 Authorization 字段里面。
另一種做法是, 跨域的時候, JWT就放在POST請求的數(shù)據(jù)體里。 JWT 的作用JWT最開始的初衷是為了實現(xiàn)授權(quán)和身份認證作用的,可以實現(xiàn)無狀態(tài),分布式的Web應(yīng)用授權(quán)。大致實現(xiàn)的流程如下
這里需要注意:不是每次請求都要申請一次Token,這是需要注意,如果不是對于安全性要求的情況,不建議每次都申請,因為會增加業(yè)務(wù)耗時;比如只在登陸時申請,然后使用JWT的過期時間或其他手段來保證JWT的有效性; Acesss Token,Refresh TokenJWT最大的優(yōu)勢是服務(wù)器不再需要存儲Session,使得服務(wù)器認證鑒權(quán)業(yè)務(wù)可以方便擴展。這也是JWT最大的缺點由于服務(wù)器不需要存儲Session狀態(tài),因此使用過程中無法廢棄某個Token,或者更改Token的權(quán)限。也就是說一旦JWT簽發(fā)了,到期之前就會始終有效。 我們可以基于上面提到的問題做一些改進。 前面講的Token,都是Acesss Token,也就是訪問資源接口時所需要的Token,還有另外一種Token,Refresh Token。一般情況下,Refresh Token的有效期會比較長。而Access Token的有效期比較短,當Acesss Token由于過期而失效時,使用Refresh Token就可以獲取到新的Token,如果Refresh Token也失效了,用戶就只能重新登錄了。Refresh Token及過期時間是存儲在服務(wù)器的數(shù)據(jù)庫中,只有在申請新的Acesss Token時才會驗證,不會對業(yè)務(wù)接口響應(yīng)時間造成影響,也不需要向Session一樣一直保持在內(nèi)存中以應(yīng)對大量的請求。
一個簡單的JWT使用示例準備
服務(wù)端代碼
客戶端代碼
運行代碼
區(qū)別Cookie和Session的區(qū)別
Token和Session的區(qū)別Session是一種HTTP儲存機制, 為無狀態(tài)的HTTP提供持久機制; Token就是令牌, 比如你授權(quán)(登錄)一個程序時,它就是個依據(jù),判斷你是否已經(jīng)授權(quán)該軟件; Session和Token并不矛盾,作為身份認證Token安全性比Session好,因為每一個請求都有簽名還能防止監(jiān)聽以及重放攻擊,而Session就必須依賴鏈路層來保障通訊安全了。如上所說,如果你需要實現(xiàn)有狀態(tài)的回話,仍然可以增加Session來在服務(wù)端保存一些狀態(tài)。 總結(jié)cookie,session,Token沒有絕對的好與壞之分,只要還是要結(jié)合實際的業(yè)務(wù)場景和需求來決定采用哪種方式來管理回話,當然也可以三種都用。 參考作者:木子星兮 鏈接:https:///post/5d01f82cf265da1b67210869 來源:掘金 著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 |
|
|
來自: python_lover > 《待分類》