How to use PHP JWT in Web

Time:2020-10-27

Explain JWT

JWT is a string, which is encrypted and verified by three parts. Token based authentication can replace the traditional cookie + session authentication method. The three parts are as follows:

 header.payload.signature

Header part

The header format is:

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

This is a JSON string. Both fields are required,algField specifies the buildsignatureThe default value isHS256, you can specify other encryption algorithms, such asRSA. throughbase64encodeYou can get itheader.

Part of payload

The basic components of playload are as follows:

Simple:

$payload=[
            'ISS' = > $issuer, // issuer
            'iat' => $_ SERVER['REQUEST_ Time '], // when was it issued
            'exp' => $_ SERVER['REQUEST_ Time '] + 7200 // expiration time
            'uid'=>1111
        ];

Complicating point: the official statement consists of three parts(Reserved claimsPublic claims,Private claims)

$token   = [
            #Not necessarily. The sender request entity can be the information of the user who initiated the request, or the signer of JWT.
            "iss"       => "http://example.org",
            #Not necessarily. issued at。  Token creation time, UNIX timestamp format
            "iat"       => $_SERVER['REQUEST_TIME'],
            #Not necessarily. Expire specifies the lifetime of the token. UNIX timestamp format
            "exp"       => $_SERVER['REQUEST_TIME'] + 7200,
            #Not necessarily. The party receiving the JWT.
            "aud"       => "http://example.com",
            #Not necessarily. The users the JWT is targeting
            "sub"       => "[email protected]",
            #Not necessarily. not before。 If the current time is before the time in NBF, the token will not be accepted; generally, some space will be left, such as a few minutes.
            "nbf"       => 1357000000,
            #Not necessarily. JWT ID。 Unique identifier for the current token
            "jti"       => '222we',
            #Custom fields
            "GivenName" => "Jonny",
            #Custom fields
            "name"   => "Rocket",
            #Custom fields
            "Email"     => "[email protected]",
         
        ];

payloadIt is also a JSON data, which indicates the user’s identity. You can customize the fields by yourself, which is very flexible. You can also use it simply, in a simple way. afterjson_encodeandbase64_encodeYou can get itpayload

Signature components

takeheaderandpayloadUse the encryption algorithm specified in the header to encrypt. Of course, the encryption process also needs to define the secret key. You can select a string by yourself.

Example of official website:

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

Self use:

<?php

    public static function encode(array $payload, string $key, string $alg = 'SHA256')
    {
        $key = md5($key);
        $jwt = self::urlsafeB64Encode(json_encode(['typ' => 'JWT', 'alg' => $alg])) . '.' . self::urlsafeB64Encode(json_encode($payload));
        return $jwt . '.' . self::signature($jwt, $key, $alg);
    }

   public static function signature(string $input, string $key, string $alg)
    {
        return hash_hmac($alg, $input, $key);
    }

These three parts are used.Connected together, it’s tallJWTAnd then you can use it

JWT usage process

Official use process description:
How to use PHP JWT in Web

translate:

  • First login: the user enters the user name and password for the first time
  • Password verification: the server extracts the user name and password from the database for verification
  • Generate JWT: the server side verifies and generates JWT according to the information returned from the database and preset rules
  • Return JWT: the server returns JWT in HTTP response
  • Request with JWT: after the client initiates a request, the authorization field in HTTP request header must have a value, which is JWT

JWT verification process

Because I wrote it by myself, I didn’t use the framework, so I still need to record the verification process

The client has aJWTInformation, back end access$_SERVER[HTTP_AUTHORIZATION]:
How to use PHP JWT in Web

But be careful. This is mineAuthorizationNo moreBearerIn official useBearerYou can also use it yourself:

Authorization: Bearer <token>

PHP verification pseudocode:

<?php
public static function decode(string $jwt, string $key)
    {
        $tokens = explode('.', $jwt);
        $key    = md5($key);

        if (count($tokens) != 3)
            return false;

        list($header64, $payload64, $sign) = $tokens;

        $header = json_decode(self::urlsafeB64Decode($header64), JSON_OBJECT_AS_ARRAY);
        if (empty($header['alg']))
            return false;

        if (self::signature($header64 . '.' . $payload64, $key, $header['alg']) !== $sign)
            return false;

        $payload = json_decode(self::urlsafeB64Decode($payload64), JSON_OBJECT_AS_ARRAY);

        $time = $_SERVER['REQUEST_TIME'];
        if (isset($payload['iat']) && $payload['iat'] > $time)
            return false;

        if (isset($payload['exp']) && $payload['exp'] < $time)
            return false;

        return $payload;
    }

 public static function urlsafeB64Decode(string $input)
    {
        $remainder = strlen($input) % 4;

        if ($remainder)
        {
            $padlen = 4 - $remainder;
            $input .= str_repeat('=', $padlen);
        }

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

Reference articles:
https://jwt.io/introduction/
http://www.cnblogs.com/zjutzz…