shiro使用(使用token預熱,爲什麼要使用token)

既然要做,就做的細緻一點,對得起自己!

常見問題:1.是否思考過傳統web項目是如何進行請求合法性的驗證?請看第一部分

                  2.是否認真思考過token和Session相比真正的優勢在哪裏?請看簡單總結

                 3.使用token的正確姿勢是什麼?請看問題思考

第一部分:傳統web(前後端沒有分離的時代)項目是如何保證服務器接收的請求都是合法的?(這裏的合法請求是指服務器經過認證的)

常見場景:1.系統開發人員在編寫代碼過程中一點都沒有做請求的校驗,安全性爲0!

                  2.系統開發人員統一使用Session進行請求的判斷,即在登錄認證成功之後,將用戶信息存儲在session中,凡是涉及到校驗權限的請求,在相關代碼裏,都要從當前Session中提取信息,(如果你存儲在session裏,但是你又不在Session裏控制,那意義何在?)成功則合法,沒有則引導用戶登錄!

                  對於第2步來說,結合shiro使用之後,shiro會自動將用戶信息存儲在shiro的Session中,如下圖,取出Session中信息則可以通過User user = (User) SecurityUtils.getSubject().getPrincipal()獲取

如圖

服務端使用Session的弊端以及爲何要使用token的文章,請看這裏,或者可以自行去各大技術論壇搜索相關文章即可。

簡單總結一下網上的個人覺得靠譜的答案:

1.首先Session如果存儲在服務器內存中,如果Session過多,勢必會影響服務器性能

2.Session如果存儲在服務器內存中,在大型分佈式中(服務器很多臺的情況下)很難做到多個服務器之間Session共享,也不是有解決方案,具體可參考 深入分析JavaWeb技術內幕一書中關於Session的章節

3.Session和對應的SessionId可以存儲在數據庫中(不要被網上有些文章誤導了,說什麼只能存在內存中),雖然絕大多數情況下是存儲在內存中。客戶端拿着SessionId去服務器內存或者數據庫中查找對應的Session。

4.token一般放在請求頭中,在前後端分離的時代,服務器認證通過之後,會返回給客戶端一個token,在vue項目中,將這個token設置在全局cookie中,每次請求通過interceptors.request.use這個攔截,動態地爲每個請求帶上剛剛那個token

5.token和Session一樣,都可以存儲在數據庫,都設置有過期時間。

6.在移動端,token的應用價值更高,因爲移動端不支持Cookie

問題思考:關於token的存儲問題?

服務器如何校驗請求中的token是否爲登錄認證的時返回給客戶端的token?

1.將token值和創建時間和過期時間保存在數據庫,每一次請求根據token去數據庫裏進行查詢比對,來判斷是否合法。但是這種方式和將Session存儲在數據庫裏沒啥區別啊,每次請求都要進行數據庫的查詢操作,當請求很多時,數據庫壓力也很大,同時還要定期刪除過期的token,這麼難受的,那爲什麼還要用你啊?

2.將token值和創建時間和過期時間保存redis中,這樣可以保證請求多的時候,redis數據庫可以很好的扛住壓力,同時redis也提供了key的過期時間,解決了1中的兩個問題,但是同樣的解決方式也可以用在Session上啊,那爲什麼還要用你啊?(Session也不是沒有分佈式解決方案的,總不能爲了用token而用toke吧,他的厲害之處在哪)

3.不存儲token,無論在緩存中或者數據庫中。toekn和session相比,最重要的優勢應該在於減少服務器的壓力,不論是內存壓力還是數據庫的壓力。思路大致如下:用戶登錄認證通過之後---->返回給客戶端的token應該是加密了的token,這個加密算法是關鍵,大致思路是這樣的:要將用戶的部分信息和請求的URL,時間戳融合在一起,返回給客戶端。下次客戶端請求時,會根據URL,時間戳,和部分用戶信息重新生成一個token,將這個token和客戶端請求中帶的token比較,如果相同則這次請求合法。這樣token不用佔用存儲空間,而且加解密的過程要比數據庫查詢快得多。具體也可以參考這篇文章

綜上所述,那麼token的作用就很明顯了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章