## JWT長什么樣?
JWT是由三段信息構成的,將這三段信息文本用`.`鏈接一起就構成了Jwt字符串。就像這樣:
~~~
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
~~~
## JWT的構成
### 1. 頭部(header),
jwt的頭部承載兩部分信息:
> * 聲明類型[,這里是jwt
> * 聲明加密的算法 通常直接使用 HMAC SHA256
完整的頭部就像下面這樣的JSON:
~~~bash
{
'typ': 'JWT',
'alg': 'HS256'
}
~~~
然后將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分.
~~~
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
~~~
### 2. 第二部分載荷(payload,),
載荷就是存放有效信息的地方。
>* 標準中注冊的聲明
>* 公共的聲明
>* 私有的聲明
**標準中注冊的聲明** (建議但不強制使用) :
* **iss**: jwt簽發者
* **sub**: jwt所面向的用戶
* **aud**: 接收jwt的一方
* **exp**: jwt的過期時間,這個過期時間必須要大于簽發時間
* **nbf**: 定義在什么時間之前,該jwt都是不可用的.
* **iat**: jwt的簽發時間
* **jti**: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
**公共的聲明** :
公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密.
**私有的聲明** :
私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。
定義一個payload:
~~~json
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
~~~
然后將其進行base64加密,得到Jwt的第二部分。
~~~
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
~~~
### playload 基本組成部分:
> 簡單點:
~~~
$payload=[
'iss' => $issuer, //簽發者
'iat' => $_SERVER['REQUEST_TIME'], //什么時候簽發的
'exp' => $_SERVER['REQUEST_TIME'] + 7200 //過期時間
'uid'=>1111
];
~~~
> 復雜點:官方說法,三個部分組成(`Reserved claims`,`Public claims`,`Private claims`)
~~~
$token = [
#非必須。issuer 請求實體,可以是發起請求的用戶的信息,也可是jwt的簽發者。
"iss" => "http://maicaii.org",
#非必須。issued at。 token創建時間,unix時間戳格式
"iat" => $_SERVER['REQUEST_TIME'],
#非必須。expire 指定token的生命周期。unix時間戳格式
"exp" => $_SERVER['REQUEST_TIME'] + 7200,
#非必須。接收該JWT的一方。
"aud" => "http://maicaii.com",
#非必須。該JWT所面向的用戶
"sub" => "admin",
# 非必須。not before。如果當前時間在nbf里的時間之前,則Token不被接受;一般都會留一些余地,比如幾分鐘。
"nbf" => 50000,
# 非必須。JWT ID。針對當前token的唯一標識
"jti" => '222we',
# 自定義字段
"name" => "Gonggui",
# 自定義字段
"Phone" => "13222222222",
];
~~~
### 3. 第三部分是簽證(signature).
jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成:
* header (base64后的)
* payload (base64后的)
* secret
這個部分需要base64加密后的header和base64加密后的payload使用`.`連接組成的字符串,然后通過header中聲明的加密方式進行加鹽`secret`組合加密,然后就構成了jwt的第三部分。
~~~csharp
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
~~~
將這三部分用`.`連接成一個完整的字符串,構成了最終的jwt:
~~~csharp
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
~~~
**注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發jwt了。**
### 如何應用
一般是在請求頭里加入`Authorization`,并加上`Bearer`標注:
~~~bash
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})
~~~
- 序言
- ThinkPHP官方資源
- 術語
- 根目錄
- php術語
- jwt
- 下載jwt
- 認識jwt
- 生成token
- 驗證token
- lcobucci/jwt
- 安裝
- 配置
- 生成token
- 解析令牌
- 驗證令牌
- 擴展庫jwt
- thinkPHP使用lcobucci/jwt
- phpmailer
- PHPMailer的使用
- phpMailer config
- 短信驗證嗎
- 阿里云短信驗證碼發送類
- 權限管理
- 基于thinkphp6.0
- 通用函數
- 密碼加密
- 數組
- 數據庫
- 查詢數據
- 添加數據
- 刪除數據
- 批量刪除
- 更新數據
- 請求流程
- thinkphp6安裝
- thinkphp6目錄介紹
- 單應用
- 多應用
- 配置文件
- 模型,模板與Model的區別
- .env介紹
- 入口文件
- 控制器
- model層
- 視圖層
- common公共函數
- 路由
- 命令行
- 常用thinkphp函數和方法
- 高德地圖i定位城市
- 更新日志