PHP JWT token實現


 
原文鏈接:https://www.jb51.net/article/146790.htm
 
機制:

 

 

 
代碼如下:
 
<?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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM