# :-: **php-jwt用戶認證**
## 介紹
全稱JSON Web Token,[基于JSON的開放標準((RFC 7519)](https://tools.ietf.org/html/rfc7519)?,以token的方式代替傳統的Cookie-Session模式,用于各服務器、客戶端傳遞信息簽名驗證。
## 優點
1:服務端不需要保存傳統會話信息,沒有跨域傳輸問題,減小服務器開銷。
2:jwt構成簡單,占用很少的字節,便于傳輸。
3:json格式通用,不同語言之間都可以使用。
## JWT組成
1:jwt由三部分組成:
? ? ?頭部(header)
? ? ?載荷(payload) 包含一些定義信息和自定義信息
? ? ?簽證(signature)
2:具體構成:
header:
```
{
"type" : "JWT", //聲明類型jwt
"alg" : "HS256" //聲明簽名算法為 SHA256
}
```
載荷(payload)
```
{
"iss": "qdzg.ctvit.tv",
"aud": "qdzg.ctvit.tv",
"iat": 1617001883
"nbf": 1617001883
"exp": 1617001943
"data": {
"userid": 1,
"username": "小名"
}
}
```
載荷包括兩部分:標準聲明和其他聲明。
標準聲明:JWT標準規定的聲明,但不是必須填寫的;
標準聲明字段:
接收該JWT的一方
iss:?jwt簽發者
sub:?jwt所面向的用戶
aud:?接收jwt的一方
exp:?jwt的過期時間,過期時間必須要大于簽發時間
nbf:?定義在什么時間之前,某個時間點后才能訪問
iat:?jwt的簽發時間
jti:?jwt的唯一身份標識,主要用來作為一次性token。
其他聲明:自己定義的字段,因為這部分是可以解開的,建議不要加入敏感信息,這里的data就是我自己定義的聲明
## 使用
php 有很多jwt的包,本人使用的是 Firebase\JWT ,具體自己想使用那個包可以自己去github官網下載
1:使用composer 拉取組件,如果沒有裝composer的 先安裝composer 并配置環境變量
```
composer require firebase/php-jwt
```
執行完命令 如果命令行有如下輸出則說明安裝成功
```
Using version ^5.2 for firebase/php-jwt
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing firebase/php-jwt (v5.2.1): Downloading (100%)
Package phpoffice/phpexcel is abandoned, you should avoid using it. Use phpoffice/phpspreadsheet instead.
Writing lock file
Generating autoload files
```
2:生成token
```
namespace app\index\controller;
use Firebase\JWT\JWT;
class Index
{
public function index(){
$key = 'ctvit.tv'; //key
$time = time();//當前時間
$data = array(
'iss' =>'qdzg.ctvit.tv',//簽發者 可選
'aud' => 'qdzg.ctvit.tv',//接收該JWT的一方,可選
'iat' =>$time,//簽發時間
'nbf' => $time,//(Not Before):某個時間點后才能訪問,比如設置time+30,表示當前時間30秒后才能使用
'exp' =>$time + 60,//過期時間,這里設置2個小時
'string'=>'qdzg.ctvit.tv',//自定義信息,不要定義敏感信息
);
$jwt = JWT::encode($data,$key,'HS256');
dump($jwt);
}
}
```
3:解析token 因為是測試demo 所以直接寫簽名
```
<?php
namespace app\index\controller;
use Firebase\JWT\JWT;
class Index
{
public function test(){
$key = 'ctvit.tv';
$jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJxZHpnLmN0dml0LnR2IiwiYXVkIjoicWR6Zy5jdHZpdC50diIsImlhdCI6MTYxNzAwMTg4MywibmJmIjoxNjE3MDAxODgzLCJleHAiOjE2MTcwMDE5NDMsInN0cmluZyI6InFkemcuY3R2aXQudHYifQ.aS_BX36WrkeGX9r9P_TeN7E0WZU67C6uQOe-W4ZcfEg';
JWT::$leeway = 60;//當前時間減去60,把時間留點余地
$decoded = JWT::decode($jwt,$key,['HS256']);
dump((array)$decoded);
}
}
```
上面代碼的輸出結果
~~~
array(6) {
["iss"] => string(13) "qdzg.ctvit.tv"
["aud"] => string(13) "qdzg.ctvit.tv"
["iat"] => int(1617001883)
["nbf"] => int(1617001883)
["exp"] => int(1617001943)
["string"] => string(13) "qdzg.ctvit.tv"
}
~~~