1.JWT以什么樣的形式存在?
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
2.JWT的構成?
第一部分我們稱它為頭部(header),第二部分我們稱其為載荷(payload, 類似於飛機上承載的物品),第三部分是簽證(signature).
3.JWT的頭部header
jwt的頭部承載兩部分信息:
- 聲明類型,這里是jwt
- 聲明加密的算法 通常直接使用 HMAC SHA256
如下列例子:然后將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分.
{ 'typ': 'JWT', 'alg': 'HS256' }
4.base64編解碼
echo 'abc' | base64 編碼
echo 'sdfsd==' | base64 -D 解碼
5.載荷(payload)就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分,將其進行base64位編碼,然后形成第二部分。
- 標准中注冊的聲明
- 公共的聲明
- 私有的聲明
{ "sub": "1234567890", "name": "John Doe", "admin": true }
6.簽證(signature)由三部分組成,經過base64位編碼后的(header,payload,secret加密方式)
這個部分需要base64加密后的header和base64加密后的payload使用.
連接組成的字符串,然后通過header中聲明的加密方式進行加鹽secret
組合加密,然后就構成了jwt的第三部分。
// javascript var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload); var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味着客戶端是可以自我簽發jwt了。
7.應用JWT
一般是在請求頭里加入Authorization
,並加上Bearer
fetch('api/user/1', { headers: { 'Authorization': 'Bearer ' + token } })
8.JWT驗證流程
(1)瀏覽器端(客戶端)post/user/login + username and password 瀏覽器在登錄表單中輸入用戶名密碼進行登錄操作。
(2)服務器接收到了用戶名密碼后,利用secret加密方式生成一個JWT,
(3)將該JWT返回給瀏覽器browser
(4)瀏覽器接收到JWT之后,將JWT放在自己的請求頭中,想服務器端請求數據
(5)服務器端檢查JWT的簽證,獲取到JWT中的payload中的聲明信息
(6)然后將請求的數據響應給瀏覽器
9.JWT的優點
- 因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
- 因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。
- 便於傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便於傳輸的。
- 它不需要在服務端保存會話信息, 所以它易於應用的擴展
10.JWT的注意事項
- 不應該在jwt的payload部分存放敏感信息,因為該部分是客戶端可解密的部分。
- 保護好secret私鑰,該私鑰非常重要。
- 如果可以,請使用https協議