JSON Web Token(JWT)是一個非常輕巧的規范。這個規范允許我們使用JWT在用戶和服務器之間傳遞安全可靠的信息。
JWT的組成
一個JWT實際上就是一個字符串,它由三部分組成:頭部、載荷與簽名。將這三段信息文本用.鏈接一起就構成了Jwt字符串。就像這樣:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
頭部(Header)
JWT的頭部承載兩部分信息:
1、聲明類型,這里是jwt
2、聲明加密的算法,通常直接使用 HMAC SHA256
{ "typ": "JWT", "alg": "HS256" }
在頭部指明了簽名算法是HS256算法。
載荷(Payload)
載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分
1、標准中注冊的聲明
2、公共的聲明
3、私有的聲明
標准中注冊的聲明 (建議但不強制使用) :
1、iss(Issuer): 簽發人
2、sub(Subject): 主題
3、aud(Audience): 受眾
4、exp(Expiration Time): 過期時間,這個過期時間必須要大於簽發時間
5、nbf(Not Before): 生效時間
6、iat(Issued At): 簽發時間
7、jti(JWT ID) : JWT的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
公共的聲明 :
公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密.
私有的聲明 :
私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味着該部分信息可以歸類為明文信息。
定義一個payload:
{ "sub": "1234567890", "name": "John Doe", "admin": true }
然后將其進行base64加密,得到Jwt的第二部分。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
簽名(Signature)
JWT的第三部分是一個簽證信息,這個簽證信息由三部分組成:
1、header (base64后的)
2、payload (base64后的)
3、secret
這個部分需要base64加密后的header和base64加密后的payload使用.
連接組成的字符串,然后通過header中聲明的加密方式進行加鹽secret
組合加密,然后就構成了JWT的第三部分。
Signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret); Token = base64(頭部).base64(載荷).Signature
注意:secret是保存在服務器端的,在任何場景都不應該流露出去。
如何應用
一般是在請求頭里加入Authorization
,並加上Bearer
標注:
fetch('api/user/1', { headers: { 'Authorization': 'Bearer ' + token } })
服務端會驗證token,如果驗證通過就會返回相應的資源。整個流程就是這樣的:
參考文章:
https://www.jianshu.com/p/576dbf44b2ae
https://www.cnblogs.com/xiekeli/p/5607107.html
https://www.cnblogs.com/dinglinyong/p/6611151.html
https://blog.csdn.net/m0_37859660/article/details/82716162
https://blog.csdn.net/mn_kw/article/details/80522565
https://blog.csdn.net/xunfeng13/article/details/52371562/