詳解thinkphp6.0.7中怎么使用JWT

下面thinkphp框架教程欄目將給大家介紹關于thinkphp6.0.7中怎么使用jwt,希望對需要的朋友有所幫助!

thinkphp6.0.7中使用JWT超詳細解說(含代碼)

JWT是什么

JWT是json web token縮寫。它將用戶信息加密到token里,服務器不保存任何用戶信息。服務器通過使用保存的密鑰驗證token的正確性,只要正確即通過驗證。基于token的身份驗證可以替代傳統的cookie+session身份驗證方法。

基于session的登錄認證

立即學習PHP免費學習筆記(深入)”;

在傳統的用戶登錄認證中,因為http是無狀態的,所以都是采用session方式。用戶登錄成功,服務端會保證一個session,當然會給客戶端一個sessionId,客戶端會把sessionId保存在cookie中,每次請求都會攜帶這個sessionId。

cookie+session這種模式通常是保存在內存中,而且服務從單服務到多服務會面臨的session共享問題,隨著用戶量的增多,開銷就會越大。而JWT不是這樣的,只需要服務端生成token,客戶端保存這個token,每次請求攜帶這個token,服務端認證解析就可。

JWT由三個部分組成:header.payload.signature

header部分:

  {       "alg": "HS256",       "typ": "JWT"     }
對應base64UrlEncode編碼為:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 說明:該字段為json格式。alg字段指定了生成signature的算法,默認值為 HS256,typ默認值為JWT

payload部分:

    {       "sub": "1234567890",       "name": "John Doe",       "iat": 1516239022     }
對應base64UrlEncode編碼為:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 說明:該字段為json格式,表明用戶身份的數據,可以自己自定義字段,很靈活。sub 面向的用戶,name 姓名 ,iat 簽發時間。例如可自定義示例如下:
  {         "iss": "admin",           //該JWT的簽發者         "sub": "www.admin.com",   //面向的用戶         “aud”: "zhangsan",        //接收jwt的一方         "iat": 1535967430,        //簽發時間         "exp": 1535974630,        //過期時間         "nbf": 1535967430,        //該時間之前不接收處理該Token          "jti": "9f10e796726e332cec401c569969e13e"   //該Token唯一標識     }

signature部分:

    HMACSHA256(       base64UrlEncode(header) + "." +       base64UrlEncode(payload),       123456     )
對應的簽名為:keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU  最終得到的JWT的Token為(header.payload.signature):eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU 說明:對header和payload進行base64UrlEncode編碼后進行拼接。通過key(這里是123456)進行HS256算法簽名。

JWT使用流程

初次登錄:用戶初次登錄,輸入用戶名密碼 密碼驗證:服務器從數據庫取出用戶名和密碼進行驗證 生成JWT:服務器端驗證通過,根據從數據庫返回的信息,以及預設規則,生成JWT 返還JWT:服務器的HTTP RESPONSE中將JWT返還 帶JWT的請求:以后客戶端發起請求,HTTP REQUEST HEADER中的Authorizatio字段都要有值,為JWT 服務器驗證JWT

jwt版本

php中jwt有多個版本:我選擇的是最新版本。別問為什么,你買電子產品都是買新不買舊呢。看圖可以發現4.1.0的版本支持更多參數。具體參數下面會解釋

詳解thinkphp6.0.7中怎么使用JWT
安裝jwt

1、使用composer安裝

composer require lcobucci/jwt

2、從github上下載

點我跳轉到github地址:thinkphp

依賴

PHP 5.5+ OpenSSL擴展

使用

參數解釋

在使用之前先解釋下上面參數的意思:
名稱 解釋
iss (issuer) issuer 請求實體,可以是發起請求的用戶的信息,也可是jwt的簽發者
sub (Subject) 設置主題,類似于發郵件時的主題
aud (audience) 接收jwt的一方
exp (expire) token過期時間
nbf (not before) 當前時間在nbf設定時間之前,該token無法使用
iat (issued at) token創建時間
jti (JWT ID) 對當前token設置唯一標示

PHP如何實現JWT

本人使用的是PHP 7.3.4,不廢話,直接上代碼,新建jwt.php,復制粘貼如下:

<?php /**  * PHP實現jwt  */ class Jwt {       //頭部     private static $header=array(         'alg'=>'HS256', //生成signature的算法         'typ'=>'JWT'    //類型     );       //使用HMAC生成信息摘要時所使用的密鑰     private static $key='123456';         /**      * 獲取jwt token      * @param array $payload jwt載荷   格式如下非必須      * [      *  'iss'=>'jwt_admin',  //該JWT的簽發者      *  'iat'=>time(),  //簽發時間      *  'exp'=>time()+7200,  //過期時間      *  'nbf'=>time()+60,  //該時間之前不接收處理該Token      *  'sub'=>'www.admin.com',  //面向的用戶      *  'jti'=>md5(uniqid('JWT').time())  //該Token唯一標識      * ]      * @return bool|string      */     public static function getToken(array $payload)     {         if(is_array($payload))         {             $base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));             $base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));             $token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);             return $token;         }else{             return false;         }     }         /**      * 驗證token是否有效,默認驗證exp,nbf,iat時間      * @param string $Token 需要驗證的token      * @return bool|string      */     public static function verifyToken(string $Token)     {         $tokens = explode('.', $Token);         if (count($tokens) != 3)             return false;           list($base64header, $base64payload, $sign) = $tokens;           //獲取jwt算法         $base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);         if (empty($base64decodeheader['alg']))             return false;           //簽名驗證         if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)             return false;           $payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);           //簽發時間大于當前服務器時間驗證失敗         if (isset($payload['iat']) && $payload['iat'] > time())             return false;           //過期時間小宇當前服務器時間驗證失敗         if (isset($payload['exp']) && $payload['exp'] < time())             return false;           //該nbf時間之前不接收處理該Token         if (isset($payload['nbf']) && $payload['nbf'] > time())             return false;           return $payload;     }        /**      * base64UrlEncode   https://jwt.io/  中base64UrlEncode編碼實現      * @param string $input 需要編碼的字符串      * @return string      */     private static function base64UrlEncode(string $input)     {         return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));     }       /**      * base64UrlEncode  https://jwt.io/  中base64UrlEncode解碼實現      * @param string $input 需要解碼的字符串      * @return bool|string      */     private static function base64UrlDecode(string $input)     {         $remainder = strlen($input) % 4;         if ($remainder) {             $addlen = 4 - $remainder;             $input .= str_repeat('=', $addlen);         }         return base64_decode(strtr($input, '-_', '+/'));     }       /**      * HMACSHA256簽名   https://jwt.io/  中HMACSHA256簽名實現      * @param string $input 為base64UrlEncode(header).".".base64UrlEncode(payload)      * @param string $key      * @param string $alg   算法方式      * @return mixed      */     private static function signature(string $input, string $key, string $alg = 'HS256')     {         $alg_config=array(             'HS256'=>'sha256'         );         return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));     } }       //***********測試和官網是否匹配begin****************************     $payload=array('sub'=>'1234567890','name'=>'John Doe','iat'=>1516239022);     $jwt=new Jwt;     $token=$jwt->getToken($payload);     echo "<pre class="brush:php;toolbar:false">";     echo $token;          //對token進行驗證簽名     $getPayload=$jwt->verifyToken($token);     echo "<br><br>";     var_dump($getPayload);     echo "<br><br>";     //測試和官網是否匹配end               //自己使用測試begin     $payload_test=array('iss'=>'admin','iat'=>time(),'exp'=>time()+7200,'nbf'=>time(),'sub'=>'www.admin.com','jti'=>md5(uniqid('JWT').time()));;     $token_test=Jwt::getToken($payload_test);     echo "<pre class="brush:php;toolbar:false">";     echo $token_test;          //對token進行驗證簽名     $getPayload_test=Jwt::verifyToken($token_test);     echo "<br><br>";     var_dump($getPayload_test);     echo "<br><br>";     //自己使用時候end

?

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享