Example of php Backend Implementation JWT Authentication Method
- 2021-11-01 02:29:52
- OfStack
What is JWT
JWT is that abbreviation of json web token. It encrypts user information into token, and the server does not save any user information. The server verifies the correctness of the token by using the saved key, and passes the verification as long as it is correct. token-based authentication can replace the traditional cookie+session authentication method.
It defines a concise, self-contained method for securely transferring information between two communicating parties in the form of JSON objects. JWT can be signed using the HMAC algorithm or the public key pair of RSA. It has two characteristics:
Simple (Compact): It can be sent through URL, POST parameters or HTTP header because of the small amount of data and high transmission speed
Self-contained (Self-contained): The payload contains all the information needed by users, avoiding multiple queries to the database
JWT consists of three parts:
header.payload.signature
The following example takes JWT official website as an example
header section:
{
"alg": "HS256",
"typ": "JWT"
}
The corresponding base64UrlEncode code is: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Description: This field is in json format. The alg field specifies the algorithm for generating signature, with a default value of HS256 and a default value of typ of JWT
payload section:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
The corresponding base64UrlEncode code is: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
This field is json format, indicating the user identity of the data, you can customize the field, very flexible. sub target users, name name, iat issue time. For example, customizable examples are as follows:
{
"iss": "admin", // The JWT Issuer of
"iat": 1535967430, // Issue time
"exp": 1535974630, // Expired time
"nbf": 1535967430, // Do not receive and process the Token
"sub": "www.admin.com", // User-oriented
"jti": "9f10e796726e332cec401c569969e13e" // The Token Only 1 Identification
}
signature section:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
123456
)
The corresponding signature is: keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU
The json of the finally obtained JWT is (header. payload. signature): eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. keH6z1mmhKL113r9sQdAxxdzB6siemGMr_6ZOwU
header and payload base64UrlEncode encoding after splicing. The HS256 algorithm is signed by key (here 123456).
JWT usage flow
How to Implement JWT in PHP
The author uses PHP 7.0. 31. Don't talk nonsense, just put on the code, create a new jwt. php, and copy and paste it as follows:
<?php
/**
* PHP Realization jwt
*/
class Jwt {
// Head
private static $header=array(
'alg'=>'HS256', // Generate signature Algorithm of
'typ'=>'JWT' // Type
);
// Use HMAC Key used when generating information summary
private static $key='123456';
/**
* Get jwt token
* @param array $payload jwt Load The format is not required as follows
* [
* 'iss'=>'jwt_admin', // The JWT Issuer of
* 'iat'=>time(), // Issue time
* 'exp'=>time()+7200, // Expired time
* 'nbf'=>time()+60, // Do not receive and process the Token
* 'sub'=>'www.admin.com', // User-oriented
* 'jti'=>md5(uniqid('JWT').time()) // The Token Only 1 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;
}
}
/**
* Validation token Is it valid , Default authentication exp,nbf,iat Time
* @param string $Token That needs to be verified token
* @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);
// Verification failed when the issuing time is greater than the current server time
if (isset($payload['iat']) && $payload['iat'] > time())
return false;
// Expiration time Xiaoyu current server time verification failed
if (isset($payload['exp']) && $payload['exp'] < time())
return false;
// The nbf Do not receive and process the Token
if (isset($payload['nbf']) && $payload['nbf'] > time())
return false;
return $payload;
}
/**
* base64UrlEncode https://jwt.io/ Medium base64UrlEncode Coding implementation
* @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/ Medium base64UrlEncode Decoding implementation
* @param string $input String to be decoded
* @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 https://jwt.io/ Medium HMACSHA256 Signature implementation
* @param string $input For base64UrlEncode(header).".".base64UrlEncode(payload)
* @param string $key
* @param string $alg Algorithm mode
* @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));
}
}
// Test whether it matches official website begin
$payload=array('sub'=>'1234567890','name'=>'John Doe','iat'=>1516239022);
$jwt=new Jwt;
$token=$jwt->getToken($payload);
echo "<pre>";
echo $token;
// Right token Verify the signature
$getPayload=$jwt->verifyToken($token);
echo "<br><br>";
var_dump($getPayload);
echo "<br><br>";
// Test whether it matches official website end
// Use your own test 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;
// Right token Verify the signature
$getPayload_test=Jwt::verifyToken($token_test);
echo "<br><br>";
var_dump($getPayload_test);
echo "<br><br>";
// When you use it yourself end