国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

php 后端實現JWT認證方法示例

2024-05-05 00:05:13
字體:
來源:轉載
供稿:網友

JWT是什么

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

它定義了一種用于簡潔,自包含的用于通信雙方之間以 JSON 對象的形式安全傳遞信息的方法。JWT 可以使用 HMAC 算法或者是 RSA 的公鑰密鑰對進行簽名。它具備兩個特點:

簡潔(Compact):可以通過URL, POST 參數或者在 HTTP header 發送,因為數據量小,傳輸速度快

自包含(Self-contained):負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫

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

以下示例以JWT官網為例

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的簽發者  "iat": 1535967430,    //簽發時間  "exp": 1535974630,    //過期時間  "nbf": 1535967430,     //該時間之前不接收處理該Token  "sub": "www.admin.com",  //面向的用戶  "jti": "9f10e796726e332cec401c569969e13e"  //該Token唯一標識}

signature部分:

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), 123456) 

對應的簽名為:keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

最終得到的JWT的json為(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

PHP如何實現JWT

作者使用的是PHP 7.0.31,不廢話,直接上代碼,新建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>";  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>";  echo $token_test;    //對token進行驗證簽名  $getPayload_test=Jwt::verifyToken($token_test);  echo "<br><br>";  var_dump($getPayload_test);  echo "<br><br>";  //自己使用時候end

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 永新县| 陵水| 鄂尔多斯市| 盐池县| 同江市| 贞丰县| 海门市| 青冈县| 工布江达县| 西充县| 新田县| 上虞市| 满城县| 鄯善县| 陇西县| 恩施市| 临漳县| 德州市| 祥云县| 苏尼特右旗| 云和县| 阳新县| 横山县| 阿图什市| 马尔康县| 宜君县| 淮滨县| 襄城县| 永兴县| 西乌珠穆沁旗| 宜都市| 竹北市| 西青区| 台东市| 嘉祥县| 墨竹工卡县| 和林格尔县| 灵璧县| 鸡泽县| 武宣县| 镶黄旗|