JWT的介紹解析
一、什么是JWT?了解JWT,認知JWT
首先jwt其實是三個英語單詞JSON Web Token的縮寫。通過全名你可能就有一個基本的認知了。token一般都是用來認證的,比如我們系統中常用的用戶登錄token可以用來認證該用戶是否登錄。jwt也是經常作為一種安全的token使用。
JWT的定義:
JWT是一種用於雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規范。JWT作為一個開放的標准(RFC 7519),定義了一種簡潔的,自包含的方法用於通信雙方之間以Json對象的形式安全的傳遞信息。因為數字簽名的存在,這些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘鑰對進行簽名。
JWT特點:
- 簡潔(Compact): 可以通過URL,POST參數或者在HTTP header發送,因為數據量小,傳輸速度也很快
- 自包含(Self-contained):負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫
二、JWT構成或者說JWT是什么樣的?
2.1.JWT結構
JWT主要包含三個部分之間用英語句號'.'隔開
- Header 頭部
- Payload 負載
- Signature 簽名
注意,順序是 header.payload.signature
最終的結構有點像這樣:
leftso.com.blog
當然真實的jwt不可能是這么簡單的明文
2.2.JWT的頭部(Header)
在header中通常包含了兩部分:token類型和采用的加密算法。如下:
{
"alg": "HS256",
"typ": "JWT"
}
上面的JSON內容指定了當前采用的加密方式為HS256,token的類型為jwt
將上面的內容進行base64編碼,可以得到我們JWT的頭部,編碼后如下:
ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9ICA=
2.3.JWT的負載(Payload)
負載(Payload)為JWT的第二部分。JWT的標准所定義了一下幾個基本字段
iss
: 該JWT的簽發者sub
: 該JWT所面向的用戶aud
: 接收該JWT的一方exp
(expires): 什么時候過期,這里是一個Unix時間戳iat
(issued at): 在什么時候簽發的
除了標准定義的字段外,我們還要定義一些我們在業務處理中需要用到的字段,例如用戶token一般可以包含用戶登錄的token或者用戶的id,一個簡單的例子如下:
{
"iss": "Lefto.com",
"iat": 1500218077,
"exp": 1500218077,
"aud": "www.leftso.com",
"sub": "leftso@qq.com",
"user_id": "dc2c4eefe2d141490b6ca612e252f92e",
"user_token": "09f7f25cdb003699cee05759e7934fb2"
}
上面的user_id、user_token都是我們自己定義的字段
現在我們需要將負載這整個部分進行base64編碼,編碼后結果如下:
ewogICAgImlzcyI6ICJMZWZ0by5jb20iLAogICAgImlhdCI6IDE1MDAyMTgwNzcsCiAgICAiZXhwIjogMTUwMDIxODA3NywKICAgICJhdWQiOiAid3d3LmxlZnRzby5jb20iLAogICAgInN1YiI6ICJsZWZ0c29AcXEuY29tIiwKICAgICJ1c2VyX2lkIjogImRjMmM0ZWVmZTJkMTQxNDkwYjZjYTYxMmUyNTJmOTJlIiwKICAgICJ1c2VyX3Rva2VuIjogIjA5ZjdmMjVjZGIwMDM2OTljZWUwNTc1OWU3OTM0ZmIyIgp9
2.4.
Signature(簽名)
簽名其實是對JWT的頭部和負載整合的一個簽名驗證
首先需要將頭部和負載通過.鏈接起來就像這樣:header.Payload,上述的例子鏈接起來之后就是這樣的:
ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9ICA=.ewogICAgImlzcyI6ICJMZWZ0by5jb20iLAogICAgImlhdCI6IDE1MDAyMTgwNzcsCiAgICAiZXhwIjogMTUwMDIxODA3NywKICAgICJhdWQiOiAid3d3LmxlZnRzby5jb20iLAogICAgInN1YiI6ICJsZWZ0c29AcXEuY29tIiwKICAgICJ1c2VyX2lkIjogImRjMmM0ZWVmZTJkMTQxNDkwYjZjYTYxMmUyNTJmOTJlIiwKICAgICJ1c2VyX3Rva2VuIjogIjA5ZjdmMjVjZGIwMDM2OTljZWUwNTc1OWU3OTM0ZmIyIgp9
由於HMacSHA256加密算法需要一個key,我們這里key暫時用leftso吧
加密后的內容為:
686855c578362e762248f22e2cc1213dc7a6aff8ebda52247780eb6b5ae91877
其實加密的內容也就是JWT的簽名,類似我們對某個文件進行MD5加密然后接收到文件進行md5對比一樣.只是這里的HMacSHA256算法需要一個key,當然這個key應該是使用者和接收者都知道的。
對上面的簽名內容進行base64編碼得到最終的簽名
Njg2ODU1YzU3ODM2MmU3NjIyNDhmMjJlMmNjMTIxM2RjN2E2YWZmOGViZGE1MjI0Nzc4MGViNmI1YWU5MTg3Nw==
2.5最終的JWT
ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9ICA=.ewogICAgImlzcyI6ICJMZWZ0by5jb20iLAogICAgImlhdCI6IDE1MDAyMTgwNzcsCiAgICAiZXhwIjogMTUwMDIxODA3NywKICAgICJhdWQiOiAid3d3LmxlZnRzby5jb20iLAogICAgInN1YiI6ICJsZWZ0c29AcXEuY29tIiwKICAgICJ1c2VyX2lkIjogImRjMmM0ZWVmZTJkMTQxNDkwYjZjYTYxMmUyNTJmOTJlIiwKICAgICJ1c2VyX3Rva2VuIjogIjA5ZjdmMjVjZGIwMDM2OTljZWUwNTc1OWU3OTM0ZmIyIgp9.Njg2ODU1YzU3ODM2MmU3NjIyNDhmMjJlMmNjMTIxM2RjN2E2YWZmOGViZGE1MjI0Nzc4MGViNmI1YWU5MTg3Nw==