function urlsafeB64Encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function urlsafeB64Decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
public static function signature(string $input, string $key, string $alg)
{
return hash_hmac($alg, $input, $key);
}
public static function encode(array $payload, string $key, string $alg = 'SHA256'){
$key = md5($key);
$jwt = self::urlsafeB64Encode(json_encode(['type' => 'JWT', 'alg' => $alg])) . '.' . self::urlsafeB64Encode(json_encode($payload));
return $jwt . '.' . self::signature($jwt, $key, $alg);
}
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;
}