Files
alrahma_sunday_school/app/Helpers/jwt_helper.php
T
2026-02-10 22:11:06 -05:00

87 lines
2.4 KiB
PHP

<?php
if (!function_exists('base64url_encode')) {
function base64url_encode(string $data): string
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
}
if (!function_exists('jwt_encode')) {
/**
* Minimal HS256 JWT encoder.
*
* @param array $payload
* @param string $secret
* @param string $alg Only HS256 supported here
* @return string JWT string
*/
function jwt_encode(array $payload, string $secret, string $alg = 'HS256'): string
{
$header = ['typ' => 'JWT', 'alg' => $alg];
$segments = [];
$segments[] = base64url_encode(json_encode($header, JSON_UNESCAPED_SLASHES));
$segments[] = base64url_encode(json_encode($payload, JSON_UNESCAPED_SLASHES));
$signingInput = implode('.', $segments);
switch ($alg) {
case 'HS256':
$signature = hash_hmac('sha256', $signingInput, $secret, true);
break;
default:
throw new \InvalidArgumentException('Unsupported JWT alg: ' . $alg);
}
$segments[] = base64url_encode($signature);
return implode('.', $segments);
}
}
if (!function_exists('base64url_decode')) {
function base64url_decode(string $data): string
{
$padding = strlen($data) % 4;
if ($padding > 0) {
$data .= str_repeat('=', 4 - $padding);
}
return base64_decode(strtr($data, '-_', '+/'));
}
}
if (!function_exists('jwt_decode')) {
function jwt_decode(string $token, string $secret, string $alg = 'HS256'): ?array
{
$parts = explode('.', $token);
if (count($parts) !== 3) {
return null;
}
[$header64, $payload64, $signature64] = $parts;
$header = json_decode(base64url_decode($header64), true);
$payload = json_decode(base64url_decode($payload64), true);
$signature = base64url_decode($signature64);
if (!is_array($header) || !is_array($payload)) {
return null;
}
$signingInput = $header64 . '.' . $payload64;
switch ($header['alg'] ?? $alg) {
case 'HS256':
$expected = hash_hmac('sha256', $signingInput, $secret, true);
break;
default:
return null;
}
if (!hash_equals($expected, $signature)) {
return null;
}
return $payload;
}
}