### JWT
JSON Web Token (JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對象在各方之間安全地傳輸信息。該信息可以被驗證和信任,因為它是數字簽名的
### JWT使用場景
* Authorization (授權) : 這是使用JWT的最常見場景。一旦用戶登錄,后續每個請求都將包含JWT,允許用戶訪問該令牌允許的路由、服務和資源。單點登錄是現在廣泛使用的JWT的一個特性,因為它的開銷很小,并且可以輕松地跨域使用。
* Information Exchange (信息交換) : 對于安全的在各方之間傳輸信息而言,JSON Web Tokens無疑是一種很好的方式。因為JWT可以被簽名,例如,用公鑰/私鑰對,你可以確定發送人就是它們所說的那個人。另外,由于簽名是使用頭和有效負載計算的,您還可以驗證內容沒有被篡改
### JWT組成
JSON Web Token由三部分組成,它們之間用圓點(.)連接。這三部分分別是:
* Header
* Payload
* Signature
因此,一個典型的JWT看起來是這個樣子的:
```
xxxxx.yyyyy.zzzzz
```
### header
jwt的頭部承載兩部分信息:
* 聲明類型,這里是jwt
* 聲明加密的算法 通常直接使用 HMAC SHA256
完整的頭部就像下面這樣的JSON:
~~~
{
'typ': 'JWT',
'alg': 'HS256'
}
~~~
然后將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分.
~~~
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
~~~
### playload
載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分
* 標準中注冊的聲明
* 公共的聲明
* 私有的聲明
**標準中注冊的聲明** (建議但不強制使用) :
* **iss**: jwt簽發者
* **sub**: jwt所面向的用戶
* **aud**: 接收jwt的一方
* **exp**: jwt的過期時間,這個過期時間必須要大于簽發時間
* **nbf**: 定義在什么時間之前,該jwt都是不可用的.
* **iat**: jwt的簽發時間
* **jti**: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
**公共的聲明** :
公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密.
**私有的聲明** :
私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。
定義一個payload:
~~~
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
~~~
然后將其進行base64加密,得到Jwt的第二部分。
~~~
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
~~~
### signature
jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成:
* header (base64后的)
* payload (base64后的)
* secret
這個部分需要base64加密后的header和base64加密后的payload使用`.`連接組成的字符串,然后通過header中聲明的加密方式進行加鹽`secret`組合加密,然后就構成了jwt的第三部分。
~~~
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
~~~
將這三部分用`.`連接成一個完整的字符串,構成了最終的jwt:
~~~
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
~~~
**
HMAC 算法是不可逆算法,類似 MD5 和 hash ,但多一個密鑰,密鑰(即上面的 secret)由服務端持有,客戶端把 token 發給服務端后,服務端可以把其中的頭部和載荷再加上事先的 secret 再進行一次 HMAC 加密,得到的結果和 token 的第三段進行對比,如果一樣則表明數據沒有被篡改。
注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發jwt了。**
### 優點
* 因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
* 因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。
* 便于傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便于傳輸的。
* 它不需要在服務端保存會話信息, 所以它易于應用的擴展
### 安全相關
* 不應該在jwt的payload部分存放敏感信息,因為該部分是客戶端可解密的部分。
* 保護好secret私鑰,該私鑰非常重要。
* 如果可以,請使用https協議
- 概述
- 網絡時延
- 進程間通信
- URI
- URL
- URN
- NAT
- 操作系統基礎
- 內核
- 用戶空間
- 網絡協議模型
- 四層網絡協議模型
- 鏈路層
- 以太網協議
- ARP協議
- RARP協議
- MAC地址
- 網絡層
- IP協議
- ICMP協議
- 子網掩碼
- 傳輸層
- TCP協議
- TCP慢啟動
- TCP性能
- UDP協議
- SCTP協議
- 應用層
- DNS
- TCP/IP協議族
- Socket
- Socket通信模型
- socket和TCP/IP協議族
- Socket三次握手四次揮手
- OSI七層模型
- 物理層
- 數據鏈路層
- 網絡層
- 傳輸層
- 應用層
- HTTP
- 基礎
- HTTP/1.0
- HTTP/1.1
- http2.0
- HTTP報文
- WEB瀏覽器工作機制
- HTTP事務時延
- HTTP與HTTPS區別
- 持久連接
- 用戶驗證
- web結構組件
- 代理
- 正向代理
- 反向代理
- 緩存
- 網關
- 隧道-tunnel
- Agent代理
- http協議補充
- Servlet3異步請求
- ajax
- Comet
- WebSocket
- SPDY協議
- HTTP/2
- QUIC
- WebDAV
- http方法
- http連接
- 短連接&長連接
- 管線化
- 網絡會話
- cookie
- session
- token
- jwt
- cookie與session的區別
- Spring Session
- 分布式session實現方案
- 同源策略
- 跨域
- CORS
- HTTP三大安全問題
- JWT vs OAuth
- HTTPS
- SSL&TLS
- OpenSSL
- HTTPS和TLS/SSL的關系
- X509標準和PKI
- IO模型
- IO
- I/O模型
- 傳統阻塞式I/O
- 非阻塞式I/O
- IO復用
- Connection Per Thread模式
- IO多路復用模型流程
- Reactor模式
- 單Reactor單線程
- 單Reactor多線程
- 主從Reactor多線程
- Proactor模型
- Selector模型
- 信號驅動I/O
- 異步I/O
- select/poll/epoll
- select
- poll
- epoll
- select/poll/epoll適用場景
- 零拷貝原理
- 讀取文件發送網絡內存拷貝
- 零拷貝
- Netty零拷貝
- 密碼學
- 密碼學Hash算法分類
- 加密算法
- 對稱加密
- 非對稱加密
- 數字簽名
- RSA數字簽名算法
- DSA數字簽名算法
- 數字證書
- MAC算法
- web安全
- CSRF攻擊
- XSS
- cookie劫持
- SQL注入
- DDos攻擊
- 常見面試題
- 瀏覽器工作機制和原理
- XSS如何預防
- 如何防止cookie被劫持
- 附錄
- HTTP狀態碼
- 常用的網絡端口