1、基於Session的應用開發的缺陷
在咱們傳統的B\S應用開發方式中,都是使用session進行狀態管理的,好比說:保存登陸、用戶、權限等狀態信息。這種方式的原理大體以下:程序員
- 用戶登錄以後,將狀態信息保存到session裏面。服務端自動維護sessionid,即將sessionid寫入cookie。
- cookie隨着HTTP響應,被自動保存到瀏覽器端。
- 當用戶再次發送HTTP請求,sessionid隨着cookies被帶回服務器端
- 服務器端根據sessionid,能夠找回該用戶以前保存在session裏面的數據。
固然,這整個過程當中,cookies和sessionid都是服務端和瀏覽器端自動維護的。因此從編碼層面是感知不到的,程序員只能感知到session數據的存取。可是,這種方式在有些狀況下,是不適用的。web
- 好比:非瀏覽器的客戶端、手機移動端等等,由於他們沒有瀏覽器自動維護cookies的功能。
- 好比:分佈式應用,同一個應用部署甲、乙、丙三個主機上,實現負載均衡應用,其中一個掛掉了其餘的還能負載工做。要知道session是保存在服務器內存裏面的,三個主機必定是不一樣的內存。那麼你登陸的時候訪問甲,而獲取接口數據的時候訪問乙,就沒法保證session的惟一性和共享性。
固然以上的這些狀況咱們都有方案(如redis共享session等),能夠繼續使用session來保存狀態。可是還有另一種作法就是不用session了,即開發一個無狀態的應用,JWT就是這樣的一種方案。redis
2、JWT是什麼?
筆者不想用比較高大上的名詞解釋JWT(JSON web tokens),你能夠認爲JWT是一個加密後的接口訪問密碼,而且該密碼裏面包含用戶名信息。這樣既能夠知道你是誰?又能夠知道你是否能夠訪問應用?算法
- 首先,客戶端須要向服務端申請JWT令牌,這個過程一般是登陸功能。即:由用戶名和密碼換取JWT令牌。
- 當你訪問系統其餘的接口時,在HTTP的header中攜帶JWT令牌。header的名稱能夠自定義,先後端對應上便可。
- 服務端解籤驗證JWT中的用戶標識,根據用戶標識從數據庫中加載訪問權限、用戶信息等狀態信息。
這就是JWT,以及JWT在應用服務開發中的使用方法。spring
3、JWT結構分析
下圖是我用在線的JWT解碼工具,解碼時候的截圖。注意我這裏用的是解碼,不是解密。數據庫
從圖中,咱們能夠看到JWT分爲三個部分:後端
- Header,這個部分一般是用來講明JWT使用的算法信息
- payload,這個部分一般用於攜帶一些自定義的狀態附加信息(重要的是用戶標識)。可是注意這部分是能夠明文解碼的,因此注意是用戶標識,而不該該是用戶名或者其餘用戶信息。
- signature,這部分是對前兩部分數據的簽名,防止前兩部分數據被篡改。這裏須要指定一個密鑰secret,進行簽名和解籤。
4、JWT安全麼?
不少的朋友看到上面的這個解碼文件,就會生出一個疑問?你都把JWT給解析了,並且JWT又這麼的被你們普遍熟知,它還安全麼?我用一個簡單的道理說明一下:瀏覽器
- JWT就像是一把鑰匙,用來開你家裏的鎖。用戶把鑰匙一旦丟了,家天然是不安全的。其實和使用session管理狀態是同樣的,一旦網絡或瀏覽器被劫持了,確定不安全。
- signature一般被叫作簽名,而不是密碼。好比:天王蓋地虎是簽名,寶塔鎮河妖就被用來解籤。字你全都認識,可是暗號只有知道的人才對得上。固然JWT中的暗號secret不會設計的像詩詞同樣簡單。
- JWT服務端也保存了一把鑰匙,就是暗號secret。用來數據的簽名和解籤,secret一旦丟失,全部用戶都是不安全的。因此對於IT人員,更重要的是保護secret的安全。
如何增強JWT的安全性?安全
- 避免網絡劫持,由於使用HTTP的header傳遞JWT,因此使用HTTPS傳輸更加安全。這樣在網絡層面避免了JWT的泄露。
- secret是存放在服務器端的,因此只要應用服務器不被攻破,理論上JWT是安全的。所以要保證服務器的安全。
- 那麼有沒有JWT加密算法被攻破的可能?固然有。可是對於JWT經常使用的算法要想攻破,目前已知的方法只能是暴力破解,白話說就是"試密碼"。因此要按期更換secret而且保正secret的複雜度,等破解結果出來了,你的secret已經換了。
話說回來,若是你的服務器、或者你團隊的內部人員出現漏洞,一樣沒有一種協議和算法是安全的。springboot
期待您的關注