前言
本文主要介紹基於token的身份認證方式以及介紹下JWT。
這是一個系列的,可以參考以下閱讀順序
正文
本文會首先介紹Web應用的身份認證,接著介紹基於token的身份認證並介紹常用的JWT。
身份認證
HTTP 是一種沒有狀態的協議。也就是說一個請求使用使用者名稱還有密碼通過了身份驗證,下回這個網頁再傳送請求時候,還得再驗證一下。
但在實際應用中我們需要一個機制去追蹤狀態,一個解決的方法就是傳統的session-cookie解決方案。
基於token的身份認證
近年來RESTful API開始風靡,使用HTTP header來傳遞認證令牌似乎變得理所應當,而前後端分離架構似乎正在促成越來越多的WEB應用轉而使用基於token的使用者身份認證而不是傳統的cookie+session。
一個基於token的身份認證機制主要是以下幾步
- 客戶端使用使用者名稱跟密碼請求登入
- 服務端收到請求,去驗證使用者名稱與密碼
- 驗證成功後,服務端會簽發一個 Token,再把這個 Token 傳送給客戶端
- 客戶端收到 Token 以後可以把它儲存起來,比如放在 Cookie 裡或者 Local Storage 裡
- 客戶端每次向服務端請求資源的時候需要帶著服務端簽發的 Token,比如放在HTTP自定義頭部裡
- 服務端收到請求,然後去驗證客戶端請求裡面帶著的 Token,如果驗證成功,就向客戶端返回請求的資料
這種方式的好處很多
- 無狀態,畢竟token就只是個值,而且比如像JWT這種token上還可以帶一些簡單資訊比如userId,就不像session的模式還要伺服器端還要維護session,如果是分散式的還要解決session共享的問題。
- 多平臺,多域名,如果是基於token的身份認證,可以把token附帶在HTTP自定義頭部來傳遞身份資訊,這樣我Android,IOS,WP都可以使用,一次開發,全平臺適用的API伺服器。而且cookie有域名限制,使用起來也一些限制。
JWT(json web token)
Json web token是一種產生token的標準,就我的理解這個應該是用得最多的。
一個JWT主要分三個部分
- header包含了兩部分,一個是token的型別, 這部分最後是以base64編碼的形式存放。 然後是指明用的哪個雜湊演算法加密的,比如HMAC SHA256。
- payload就是想要攜帶的資訊,這部分最後也是以base64編碼的形式存放
- signature是用來驗證token是否合法的,也是token無法被偽造的關鍵。其生成的方法下圖也有。
JWT的非對稱加密
通常大家在使用JWT的時候都是使用HmacSHA256加金鑰的加密方式,這種方式嚴格依賴金鑰,在分散式開發的過程中,通常是由認證伺服器生成JWT,然後再由資源伺服器校驗JWT的有效性,那麼這時候資源伺服器就也需要金鑰了,認證服務和資源服務很可能是不同的團隊開發和維護,金鑰在這個過程中傳遞,很有可能洩漏。金鑰一旦洩漏,對方就可以輕易的模擬一個JWTtoken出來,獲取相關資訊。
RSA非對稱加密演算法就可以很好的解決這個問題,認證伺服器使用私鑰生成JWT,資源伺服器使用公鑰去校驗JWT,認證服務去管理私鑰,公鑰開放給各個資源服務,這樣金鑰洩漏的可能性就大大降低了。
後記(後期更新)
Refresh Token(待補充)
剛剛也討論了下基於token的認證的優點,但這個方法是萬能的麼?
Stop using JWT for sessions, part 2: Why your solution doesn't work