咱們清楚 http 協議是無狀態的,也就是說,若是咱們已經認證了一個用戶,那麼他下一次請求的時候,服務器不知道我是誰,咱們就必需要再次認證。前端
咱們與瀏覽器交互時,好比說登錄成功後,你再去獲取其餘的數據,服務器能準確的給與響應,怎麼作到的呢?vue
登錄成功後,服務器會爲你開闢一塊內存區間 (能夠理解爲 session),用於存放你此次會話的一些內容,好比姓名、性別、年齡等;後端
存放數據的同時,會生成 session id來標記這塊內存區間是屬於你的,而且,這個 session id( jsessionid ) 會寫入到你的瀏覽器 cookie 中,瀏覽器
只要你瀏覽器沒關閉,每次向服務器發送請求,服務器就會從你發送過來的 cookie 中去取這個 session id,而後根據這個 session id 到相應的內存中安全
取出你以前存放的數據,可是,若是退出登陸。服務器會清除屬於你的內存區域,再登陸時,從新生成新的 session服務器
可是,上邊這種基於服務器的身份認證是有一些問題的:cookie
session 每次用戶認證後,服務器都要建立一條記錄保存用戶數據,一般發生在內存中,隨着認證經過的用戶愈來愈多,服務器的在這裏的開銷就會愈來愈大…session
Scalability : 因爲Session是在內存中的,這就帶來一些擴展性的問題。app
CORS : 當咱們想要擴展咱們的應用,讓咱們的數據被多個移動設備使用時,咱們必須考慮跨資源共享問題。當使用AJAX調用從另外一個域名下獲取資源時,咱們可能會遇到禁止請求的問題。負載均衡
CSRF : 用戶很容易受到CSRF攻擊。
基於 token 的身份認證是無狀態的,服務器或者 session 中不會存儲任何用戶信息。
採用 token 這種方式,一般咱們是要先去禁用 session 的,設置爲 session 爲 SessionCreationPolicy.STATELESS
沒有會話信息意味着應用程序能夠根據須要擴展和添加更多的機器,而沒必要擔憂用戶登陸的位置。 --- 單點登陸?
雖然這一實現可能會有所不一樣,但其主要流程以下:
- 用戶攜帶用戶名和密碼請求訪問
- 服務器校驗用戶憑據
- 應用提供一個token給客戶端
- 客戶端存儲token,而且在隨後的每一次請求中都帶着它
- 服務器校驗token並返回數據
注意:
- 每一次請求都須要token
- Token應該放在請求header中
- 咱們還須要將服務器設置爲接受來自全部域的請求,用Access-Control-Allow-Origin: *
一、無狀態和可擴展性
Tokens存儲在客戶端。徹底無狀態,可擴展。咱們的負載均衡器能夠將用戶傳遞到任意服務器,由於在任何地方都沒有狀態或會話信息。
二、安全
*Token不是Cookie。(The token, not a cookie.)每次請求的時候Token都會被髮送。並且,因爲沒有Cookie被髮送,還有助於防止CSRF攻擊。即便在你的實現中將token存儲到客戶端的Cookie中,這個Cookie也只是一種存儲機制,而非身份認證機制。沒有基於會話的信息能夠操做,由於咱們沒有會話!
還有一點,token在一段時間之後會過時,這個時候用戶須要從新登陸。這有助於咱們保持安全。還有一個概念叫token撤銷,它容許咱們根據相同的受權許可以使特定的token甚至一組token無效。*
前面一、2節,咱們瞭解了基於 token 的身份認證的一些優勢,可是目前咱們所見的系統還是基於服務器身份認證的?
首先,這兩年 vue、angular 等前端語言的火熱,顯然先後端分離已成爲互聯網項目開發的業界標準使用方式;
可是,先後端分離,必然促使開發人員的分離,畢竟,小公司全棧工程師仍是少數,因此對於 jsp 等原始人時代,
仍是有人在追捧的。