Understand how to use JWT and you will be able to implement it with PHP

Keywords: PHP JSON Database network

To implement JWT certification with php, let's first understand what JWT is.
What is JWTJWT(json web token) is an open JSON-based standard implemented to pass declarations between network applications.
JWT's declarations are typically used to transfer authenticated user identity information between identity providers and service providers in order to obtain resources from the resource server.For example, on user logins.
JWT defines a concise, self-contained method for securely transferring information between communicating parties in the form of JSON objects.JWT can sign using either the HMAC algorithm or the public key pair of RSA.

JWT has two features:

Self-contained: The load contains all the information the user needs, avoiding multiple queries to the database

Compact: Can be sent via URL, POST parameter or HTTP header because of small amount of data and fast transmission speed

 

JWT Composition

JWT consists of three parts: header, payload, signature. Let's start with an example of the official website.

header section:

The jwt header carries two pieces of information:

Declaration type, here is jwt

Declaring encryption algorithms usually use HMAC SHA256 directly

The complete head is like the following JSON:

{
 "alg""HS256",
 "typ""JWT"
}

 

The corresponding base64UrlEncode code is:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Description: The field is in json format.The alg field specifies the algorithm that generates the signature, defaulting to HS256 and typ e to JWT

 

payload section:

Load is the place where effective information is stored.

Declaration registered in the standard (recommended but not mandatory):

iss: jwt issuer

Sub: Users targeted by JWT

aud: the party receiving jwt

exp: jwt expiration time, which must be greater than the issuance time

nbf: Define when this jwt will not be available

Iat: Issuance time of JWT

Jti: The unique identity of jwt, used primarily as a one-time token to avoid replay attacks.

 

{
 "sub""1234567890",
 "name""John Doe",
 "iat"1516239022
}

The corresponding base64UrlEncode code is:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

Description: The field is in json format, indicating the user's identity of the data, you can customize the field yourself, very flexible.Subuser facing, name name, iat issuance time.For example, a customizable example is as follows:

{
  "iss""admin",     //The issuer of the JWT
  "iat"1535967430,    //Time filed
  "exp"1535974630,    //Expiration Time
  "nbf"1535967430,     //Do not receive processing the Token before this time
  "sub""www.admin.com",  //User-oriented
  "jti""9f10e796726e332cec401c569969e13e"  //The Token Unique Identification
}

 

signature section:

The third part of jwt is a visa information, which consists of three parts:

  • Header (after base64)

  • Payload (after base64)

  • secret

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

 

The corresponding signature is:

keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

The final json for the JWT is (header.payload.signature):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

Description: header and payload are spliced after base64UrlEncode encoding.Sign the HS256 algorithm with key (in this case, 123 456).

 

Process of using JWT

  • First logon: User first logon, enter user name password

  • Password validation: The server takes the user name and password from the database for validation

  • Generate JWT: Server-side validation passes, generating JWT based on information returned from the database and preset rules

  • Return JWT: Return JWT in HTTP RESPONSE of the server

  • Requests with JWT: later client initiates request, HTTP REQUEST

  • The Authorizatio field in HEADER must have a value, which is JWT

  • Server Validation JWT

 

 

How PHP implements JWT

Using PHP 7.0.31 here, we create a new file, jwtAuth.php, with the complete class code as follows:

<?php
/**
 * PHP Implement jwt
 */

class JwtAuth {

  //head
  private static $header=array(
    'alg'=>'HS256'//Algorithms for generating signature s
    'typ'=>'JWT'  //type
  );

  //Key used when generating information digest using HMAC
  private static $key='root123456';


  /**
   * Get jwt token
   * @param array $payload jwt Load format as follows is not required
   * [
   * 'iss'=>'jwt_admin', //The issuer of the JWT
   * 'iat'=>time(), //Time filed
   * 'exp'=>time()+7200, //Expiration Time
   * 'nbf'=>time()+60, //Do not receive processing the Token before this time
   * 'sub'=>'www.mano100.cn', //User-oriented
   * 'jti'=>md5(uniqid('JWT').time()) //The Token Unique Identification
   * ]
   * @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;
    }
  }


  /**
   * Verify token is valid, default validation exp,nbf,iat time
   * @param string $Token token to verify
   * @return bool|string
   */

  public static function verifyToken(string $Token)
  
{
    $tokens = explode('.', $Token);
    if (count($tokens) != 3)
      return false;

    list($base64header, $base64payload, $sign) = $tokens;

    //Get jwt algorithm
    $base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);
    if (empty($base64decodeheader['alg']))
      return false;

    //Signature Verification
    if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)
      return false;

    $payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);

    //Sign-out time greater than current server time validation failed
    if (isset($payload['iat']) && $payload['iat'] > time())
      return false;

    //Expiration Time Xiaoyu Current Server Time Validation Failed
    if (isset($payload['exp']) && $payload['exp'] < time())
      return false;

    //Do not receive and process the Token before this nbf time
    if (isset($payload['nbf']) && $payload['nbf'] > time())
      return false;

    return $payload;
  }

  /**
   * base64UrlEncode  https://jwt.io/ Encode implementation of base64UrlEncode in
   * @param string $input String to be encoded
   * @return string
   */

  private static function base64UrlEncode(string $input)
  
{
    return str_replace('=''', strtr(base64_encode($input), '+/''-_'));
  }

  /**
   * base64UrlEncode https://jwt.io/ Decoding implementation of base64UrlEncode in
   * @param string $input String to decode
   * @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 Signature. HMACSHA256 signature implementation in https://jwt.io/.
   * @param string $input For base64UrlEncode (header).'.'. base64UrlEncode (payload)
   * @param string $key
   * @param string $alg  Method of algorithm
   * @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));
  }
}

 

These are all the contents of the article. If you have friends who need to learn and exchange experience, please join Swoole Exchange Group to learn and exchange. Let's learn together, communicate with each other if you have problems, and make progress together!The premise is that you learn technology.Thanks for reading!

Click here to join the group

Test it here

//Test whether or not the official website matches begin
  $payload=array('sub'=>'1234567890','name'=>'John Doe','iat'=>1516239022);
  $jwt=new Jwt;
  $token=$jwt->getToken($payload);
  echo "<pre>";
  echo $token;

//Verify signature on token
  $getPayload=$jwt->verifyToken($token);
  echo "<br><br>";
  var_dump($getPayload);
  echo "<br><br>";
//Test whether the official website matches the end


//Use test begin yourself
  $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;

//Verify signature on token
  $getPayload_test=Jwt::verifyToken($token_test);
  echo "<br><br>";
  var_dump($getPayload_test);
  echo "<br><br>";
//end when used by oneself

Posted by _rhod on Fri, 22 Nov 2019 21:45:57 -0800