1.JWT長什么樣?
JWT:Json Web Token ,是由三段信息構成的,將這三段信息用 . 相連在一起就構成了JWT字符串:
eyJhbGciOiI6IkRFRiJ9.eNqEj0GOhCAURO_ohbw8ZqUaEUDMe6F.2A2jGp9sAw-QdkOVmm_dfD6Q
2.token的鑒權機制
http協議無狀態的,所以需要sessionId或token的鑒權機制,jwt的token認證機制不需要在服務端再保留用戶的認證信息或會話信息。這就意味着基於jwt認證機制的應用程序不需要去考慮用戶在哪一台服務器登錄了,這就為應用的擴展提供了便利,jwt更適用於分布式應用。
token認證流程上是這樣的:
- 用戶使用用戶名密碼來請求服務器進行驗證
- 服務器通過驗證,發送給用戶一個token(該jwt 不需要在服務器保存一份)
- 客戶端存儲token且在每次請求時附送上這個token值
- 服務端驗證token值,並返回業務數據
這個token必須要在每次請求時傳遞給服務端,它應該保存在請求頭里, 另外,服務端要支持CORS(跨來源資源共享)策略,
一般我們在服務端這么做就可以了Access-Control-Allow-Origin: *
一般是手動在請求頭里加入參數 ‘Authorization’,並加上 ”Bearer ” 標注(非必須):
Authorization:Bearer eyJhbGciOiI6IkRFRiJ9.eNqEj0GOhCAURO_ohbw8ZqUaEUDMe6F.2A2jGp9sAw-QdkOVmm_dfD6Q
也可以放到cookie中,讓瀏覽器發送請求時自動攜帶。
3.JWT的構成
一個JWT實際上就是一個字符串,它由三部分組成:header頭部、playload載荷、sign簽名。
3.1頭部
描述關於該JWT的最基本的信息,例如其類型以及簽名所用的算法等。表示成一個JSON對象,經base64編碼形成第一部分。
例如:
{ 'typ': 'JWT', //類型 'alg': 'HS256' //sign的加密算法 }
base64編碼:eyJhbGciOiI6IkRFRiJ9
3.2載荷
其實就是自定義的數據,一般存儲用戶Id,用戶名、過期時間等信息。也就是JWT的核心所在,因為這些數據就是使后端知道此token是哪個用戶已經登錄的憑證。而且這些數據是存在token里面的,由前端攜帶,所以后端幾乎不需要保存任何數據。
例如:
{ 'uid': '1234567', //用戶編號
'name': 'kobe', //用戶名
'exp': '20210526121212' //過期時間
}
base64編碼:eNqEj0GOhCAURO_ohbw8ZqUaEUDMe6F
3.3簽名
1.頭部和載荷各自由base64加密后用 . 連接起來,然后就形成了xxx.yyy的前兩段token。
2.最后一段token的形成:前兩段字符串xxx.yyy 加入一個密鑰用sha256算法或者其他算法加密形成不可逆的密文sign。
哈希算法生成的sign:2A2jGp9sAw-QdkOVmm_dfD6Q
4.總結
- 因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用
- 因為有了payload部分,所以JWT可以存儲一些其他業務邏輯所需要的非敏感信息,敏感信息還是不建議存放到jwt中
- 便於傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便於傳輸的
- 它不需要在服務端保存會話信息, 所以它易於應用的擴展
- 服務器保護好secret私鑰,該私鑰很重要,不能泄露
- 如果可以,請使用https協議