<?php declare(strict_types=1);
/* URL-safe Base64 encode and decode, as PHP does not natively have this function */
function base64_urlencode($subject): string
{
}
function base64_urldecode($subject): string
{
}
function jwt_encode
(string
$secret, array $header, array $payload) : string
{
$payload_code = base64_urlencode
(json_encode($payload));
$header_code,
$payload_code,
]);
$signature = hash_hmac('sha256', $token, $secret);
$signature_code = base64_urlencode($signature);
$header_code,
$payload_code,
$signature,
]
);
}
function jwt_decode
(string
$secret, string
$jwt) : array {
[$header_code, $payload_code, $signature] = explode('.', $jwt);
$header = json_decode(base64_urldecode
($header_code), true); $payload = json_decode(base64_urldecode
($payload_code), true);
$availableAlgorithms = ['HS256' => 'sha256'];
$algorithm = $availableAlgorithms[$header['alg']];
$header_code,
$payload_code,
]);
$jwt_signature = hash_hmac($algorithm, $token, $secret);
if ($jwt_signature !== $signature) {
throw new \UnexpectedValueException('Signature verification failed!');
}
return $payload;
}
$header = ['typ' => 'JWT', 'alg' => 'HS256'];
$payload = [
'This is' => 'some data'
];
$secret = 'My S3cR3t!';
$jwt = jwt_encode($secret, $header, $payload);
$jwt_payload = jwt_decode($secret, $jwt);
var_dump($jwt, $jwt_payload === $payload, $payload);
PD9waHAgZGVjbGFyZShzdHJpY3RfdHlwZXM9MSk7CgovKiBVUkwtc2FmZSBCYXNlNjQgZW5jb2RlIGFuZCBkZWNvZGUsIGFzIFBIUCBkb2VzIG5vdCBuYXRpdmVseSBoYXZlIHRoaXMgZnVuY3Rpb24gICovCmZ1bmN0aW9uIGJhc2U2NF91cmxlbmNvZGUoJHN1YmplY3QpOiBzdHJpbmcKewogICAgcmV0dXJuIHN0cnRyKHJ0cmltKGJhc2U2NF9lbmNvZGUoJHN1YmplY3QpLCAnPScpLCAnKy8nLCAnLV8nKTsKfQoKZnVuY3Rpb24gYmFzZTY0X3VybGRlY29kZSgkc3ViamVjdCk6IHN0cmluZwp7CiAgICByZXR1cm4gYmFzZTY0X2RlY29kZShzdHJ0cigkc3ViamVjdCwgJy1fJywgJysvJykpOwp9CgpmdW5jdGlvbiBqd3RfZW5jb2RlKHN0cmluZyAkc2VjcmV0LCBhcnJheSAkaGVhZGVyLCBhcnJheSAkcGF5bG9hZCkgOiBzdHJpbmcKewogICAgJGhlYWRlcl9jb2RlID0gYmFzZTY0X3VybGVuY29kZShqc29uX2VuY29kZSgkaGVhZGVyKSk7CiAgICAkcGF5bG9hZF9jb2RlID0gYmFzZTY0X3VybGVuY29kZShqc29uX2VuY29kZSgkcGF5bG9hZCkpOwoKICAgICR0b2tlbiA9IHZzcHJpbnRmKCclcy4lcycsIFsKICAgICAgICAkaGVhZGVyX2NvZGUsCiAgICAgICAgJHBheWxvYWRfY29kZSwKICAgIF0pOwoKICAgICRzaWduYXR1cmUgPSBoYXNoX2htYWMoJ3NoYTI1NicsICR0b2tlbiwgJHNlY3JldCk7CgogICAgJHNpZ25hdHVyZV9jb2RlID0gYmFzZTY0X3VybGVuY29kZSgkc2lnbmF0dXJlKTsKCiAgICByZXR1cm4gdnNwcmludGYoJyVzLiVzLiVzJywgWwogICAgICAgICAgICAkaGVhZGVyX2NvZGUsCiAgICAgICAgICAgICRwYXlsb2FkX2NvZGUsCiAgICAgICAgICAgICRzaWduYXR1cmUsCiAgICAgICAgXQogICAgKTsKfQoKZnVuY3Rpb24gand0X2RlY29kZShzdHJpbmcgJHNlY3JldCwgc3RyaW5nICRqd3QpIDogYXJyYXkKewogICAgWyRoZWFkZXJfY29kZSwgJHBheWxvYWRfY29kZSwgJHNpZ25hdHVyZV0gPSBleHBsb2RlKCcuJywgJGp3dCk7CgogICAgJGhlYWRlciA9IGpzb25fZGVjb2RlKGJhc2U2NF91cmxkZWNvZGUoJGhlYWRlcl9jb2RlKSwgdHJ1ZSk7CiAgICAkcGF5bG9hZCA9IGpzb25fZGVjb2RlKGJhc2U2NF91cmxkZWNvZGUoJHBheWxvYWRfY29kZSksIHRydWUpOwoKICAgICRhdmFpbGFibGVBbGdvcml0aG1zID0gWydIUzI1NicgPT4gJ3NoYTI1NiddOwogICAgJGFsZ29yaXRobSA9ICRhdmFpbGFibGVBbGdvcml0aG1zWyRoZWFkZXJbJ2FsZyddXTsKCiAgICAkdG9rZW4gPSB2c3ByaW50ZignJXMuJXMnLCBbCiAgICAgICAgJGhlYWRlcl9jb2RlLAogICAgICAgICRwYXlsb2FkX2NvZGUsCiAgICBdKTsKCiAgICAkand0X3NpZ25hdHVyZSA9IGhhc2hfaG1hYygkYWxnb3JpdGhtLCAkdG9rZW4sICRzZWNyZXQpOwoKICAgIGlmICgkand0X3NpZ25hdHVyZSAhPT0gJHNpZ25hdHVyZSkgewogICAgICAgIHRocm93IG5ldyBcVW5leHBlY3RlZFZhbHVlRXhjZXB0aW9uKCdTaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxlZCEnKTsKICAgIH0KCiAgICByZXR1cm4gJHBheWxvYWQ7Cn0KCiRoZWFkZXIgPSBbJ3R5cCcgPT4gJ0pXVCcsICdhbGcnID0+ICdIUzI1NiddOwoKJHBheWxvYWQgPSBbCiAgICAnVGhpcyBpcycgPT4gJ3NvbWUgZGF0YScKXTsKCiRzZWNyZXQgPSAnTXkgUzNjUjN0ISc7Cgokand0ID0gand0X2VuY29kZSgkc2VjcmV0LCAkaGVhZGVyLCAkcGF5bG9hZCk7Cgokand0X3BheWxvYWQgPSBqd3RfZGVjb2RlKCRzZWNyZXQsICRqd3QpOwoKdmFyX2R1bXAoJGp3dCwgJGp3dF9wYXlsb2FkID09PSAkcGF5bG9hZCwgJHBheWxvYWQpOwo=