ThinkPHP5-使用 think-API 部署 JWT

lanffff發表於2019-06-30

因為下一個專案要用TP5開發一個小程式,所以就使用到了,TP框架,因為小程式開發需要後臺來編寫api介面,所以就上網查了一下有沒有相關的依賴,在此推薦一下think-api擴充套件工具,因為主要想使用其中的jwt功能來判斷小程式使用者的登入狀態,下面就以本人的專案為例,簡單和大家聊一下,通過think-api來部署JWT。

1.安裝依賴

本人使用的 TP 版本是 TP5.1,擴充套件下載地址:https://github.com/czewail/think-api ,通過composer安裝依賴:

$ composer require zewail/think-api:1.1.x

2.配置說明

擴充套件安裝完畢後,我們們可以在 vendor/think-api/config/jwt.php檔案中檢視 jwt 的配置。

主要是使用者模型路徑那塊,需要修改一下:

return [
    // 加密演算法
    'algorithm'      => 'HS256',
    // HMAC演算法使用的加密字串
    'key'            => 'ex-key',
    // RSA演算法使用的私鑰檔案路徑
    'privateKeyPath' => '/home/rsa_private_key.pem',
    // RSA演算法使用的公鑰檔案路徑
    'publicKeyPath'  => '/home/rsa_public_key.pem',
    // 誤差時間,單位秒
    'deviation'      => 60,
    // 過期時間, 單位分鐘
    'ttl'            => 120,
    // 使用者模型路徑
    'user'           => app\api\model\User::class,
];

3.建立API介面控制器

通過命令列建立我們想要反回Token給前端的控制器

$ php think make:controller api/Index

4.引用依賴

在建立的檔案頭新增檔案路徑:use Zewail\Api\Facades\JWT;案例程式碼如下:

    public function index()
    {
        //獲取前臺傳送過來的登入資訊
        $tel      = $this->request->tel;
        $password = $this->request->passwword;
        //把登入資訊傳入JWT驗證匹配
        $credentials = ['tel' => $tel, 'password' => $password];
        //1.驗證通過返回token  1和2任意取一種方式
        $token = JWT::attempt($credentials);
        //2.通過已有賬戶模型生成token  1和2任意取一種方式
        $user  = User::find(84);
        $token = JWT::fromUser($user);
        $msg   = "驗證成功";
        //把token傳送給前臺確認是否成功登陸
        return $this->ApiSuccess($token, $msg);
    }

有一點需要注意因為API離預設的接收引數是 mobile 和 password 。上門的例子中是 tel 和 password 。更改了變數名稱,所以我們需要在使用者模型中接入一下程式碼來說明。以此類推。
public $jwtSub = 'tel';

5.配置路由

route/route.php中加入路由地址 Route::get('api/test', 'api/Index/index');

6.執行測試

在 postman 中測試結果如下,這樣我們們就可以在後臺生成 token 返給前臺驗證登入了。

ThinkPhp5-使用think-api部署JWT

7.驗證token(補充)

我們在 postman 中把之前生成的 token 已頭部的方式重新傳送到後臺,來進行 token 驗證,以下圖為例。

ThinkPHP5-使用 think-API 部署 JWT

之後攜帶頭部訪問驗證路由,驗證程式碼如下:

       if ($user = JWT::authenticate()) {
                return true;
        } 

如果驗證無誤就會返回true。

8.關於token不存在及token過期的問題處理(補充)

vendor\think-api\src\JWT/Factories\code.php檔案中 think-api 介面為我們們提供了對應的錯誤反饋。

// 檢查是否過期
if (isset($payload->exp) && (time() - $this->deviation) >= $payload->exp) {
    throw new TokenExpiredException('該 Token 已過期');
}
// 驗證簽名
if (!$this->verify("$header64.$payload64", $signature)) {
    throw new TokenInvalidException('無效的 Token');
}

那麼我們們如何利用這些狀態反饋呢,這就要使用前置中介軟體的方式來對前端傳送的 token 資訊進行驗證。

首先建立中介軟體:

$ php think make:middle Test 

然後在中介軟體中寫入以下內容:

    //用try catch捕獲報錯反饋
    public function handle($request, Closure $next)
    {
        try {
            if (!$user = JWT::authenticate()) {
                return response()->json([
                    'errcode' => 1004,
                    'errmsg'  => '無此使用者',

                ], 404);
            }
            return $next($request);

        } catch (TokenExpiredException $e) {

            return response()->json([
                'errcode' => 1003,
                'errmsg'  => 'token 過期', //token已過期
            ]);

        } catch (TokenInvalidException $e) {

            return response()->json([
                'errcode' => 1002,
                'errmsg'  => 'token 無效', //token無效
            ]);

        } catch (JWTException $e) {

            return response()->json([
                'errcode' => 1001,
                'errmsg'  => '缺少token', //token為空
            ]);

        }
    }

之後再在路由上門引用就可以了。

相關文章