1、基於服務器的身份認證
我們清楚 http 協議是無狀態的,也就是說,如果我們已經認證了一個用戶,那么他下一次請求的時候,服務器不知道我是誰,我們就必須要再次認證。
我們與瀏覽器交互時,比如說登陸成功后,你再去獲取其他的數據,服務器能准確的給與響應,怎么做到的呢?
登陸成功后,服務器會為你開辟一塊內存區間 (可以理解為 session),用於存放你這次會話的一些內容,比如姓名、性別、年齡等;
存放數據的同時,會生成 session id來標記這塊內存區間是屬於你的,並且,這個 session id( jsessionid ) 會寫入到你的瀏覽器 cookie 中,
只要你瀏覽器沒關閉,每次向服務器發送請求,服務器就會從你發送過來的 cookie 中去取這個 session id,然后根據這個 session id 到相應的內存中
取出你之前存放的數據,但是,如果退出登錄。服務器會清除屬於你的內存區域,再登錄時,重新生成新的 session

但是,上邊這種基於服務器的身份認證是有一些問題的:
-
session 每次用戶認證后,服務器都要創建一條記錄保存用戶數據,通常發生在內存中,隨着認證通過的用戶越來越多,服務器的在這里的開銷就會越來越大…
-
Scalability : 由於Session是在內存中的,這就帶來一些擴展性的問題。
-
CORS : 當我們想要擴展我們的應用,讓我們的數據被多個移動設備使用時,我們必須考慮跨資源共享問題。當使用AJAX調用從另一個域名下獲取資源時,我們可能會遇到禁止請求的問題。
-
CSRF : 用戶很容易受到CSRF攻擊。
2、基於 Token 的身份認證
基於 token 的身份認證是無狀態的,服務器或者 session 中不會存儲任何用戶信息。
采用 token 這種方式,通常我們是要先去禁用 session 的,設置為 session 為 SessionCreationPolicy.STATELESS
沒有會話信息意味着應用程序可以根據需要擴展和添加更多的機器,而不必擔心用戶登錄的位置。 --- 單點登錄?
雖然這一實現可能會有所不同,但其主要流程如下:
- 用戶攜帶用戶名和密碼請求訪問
- 服務器校驗用戶憑據
- 應用提供一個token給客戶端
- 客戶端存儲token,並且在隨后的每一次請求中都帶着它
- 服務器校驗token並返回數據
注意:
- 每一次請求都需要token
- Token應該放在請求header中
- 我們還需要將服務器設置為接受來自所有域的請求,用Access-Control-Allow-Origin: *
使用 token 的好處?
1、無狀態和可擴展性
Tokens存儲在客戶端。完全無狀態,可擴展。我們的負載均衡器可以將用戶傳遞到任意服務器,因為在任何地方都沒有狀態或會話信息。
2、安全
*Token不是Cookie。(The token, not a cookie.)每次請求的時候Token都會被發送。而且,由於沒有Cookie被發送,還有助於防止CSRF攻擊。即使在你的實現中將token存儲到客戶端的Cookie中,這個Cookie也只是一種存儲機制,而非身份認證機制。沒有基於會話的信息可以操作,因為我們沒有會話!
還有一點,token在一段時間以后會過期,這個時候用戶需要重新登錄。這有助於我們保持安全。還有一個概念叫token撤銷,它允許我們根據相同的授權許可使特定的token甚至一組token無效。*
3、總結
前面1、2節,我們了解了基於 token 的身份認證的一些優點,但是目前我們所見的系統仍是基於服務器身份認證的?
首先,這兩年 vue、angular 等前端語言的火熱,顯然前后端分離已成為互聯網項目開發的業界標准使用方式;
但是,前后端分離,必然促使開發人員的分離,畢竟,小公司全棧工程師還是少數,所以對於 jsp 等原始人時代,
還是有人在追捧的。