Files
epictravelexpeditions/api/includes/jwt.php
T
2026-05-22 12:52:45 +00:00

118 lines
3.0 KiB
PHP

<?php
/**
* JWT Authentication Functions
* Simple JWT implementation for PHP
*/
class JWT {
/**
* Create a JWT token
*/
public static function encode($payload, $secret) {
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
$payload = json_encode($payload);
$base64UrlHeader = self::base64UrlEncode($header);
$base64UrlPayload = self::base64UrlEncode($payload);
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true);
$base64UrlSignature = self::base64UrlEncode($signature);
return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
}
/**
* Decode and verify a JWT token
*/
public static function decode($jwt, $secret) {
$parts = explode('.', $jwt);
if (count($parts) !== 3) {
return false;
}
list($base64UrlHeader, $base64UrlPayload, $base64UrlSignature) = $parts;
$signature = self::base64UrlDecode($base64UrlSignature);
$expectedSignature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true);
if (!hash_equals($signature, $expectedSignature)) {
return false;
}
$payload = json_decode(self::base64UrlDecode($base64UrlPayload), true);
// Check expiration
if (isset($payload['exp']) && $payload['exp'] < time()) {
return false;
}
return $payload;
}
/**
* Create authentication token
*/
public static function createToken($email) {
$payload = [
'sub' => $email,
'iat' => time(),
'exp' => time() + JWT_EXPIRY
];
return self::encode($payload, JWT_SECRET_KEY);
}
/**
* Verify token from Authorization header
*/
public static function verifyToken() {
$headers = getallheaders();
if (!isset($headers['Authorization'])) {
return false;
}
$authHeader = $headers['Authorization'];
if (!preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
return false;
}
$token = $matches[1];
$payload = self::decode($token, JWT_SECRET_KEY);
return $payload;
}
/**
* Base64 URL encode
*/
private static function base64UrlEncode($data) {
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($data));
}
/**
* Base64 URL decode
*/
private static function base64UrlDecode($data) {
return base64_decode(str_replace(['-', '_'], ['+', '/'], $data));
}
}
/**
* Require authentication middleware
*/
function requireAuth() {
$payload = JWT::verifyToken();
if (!$payload) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized']);
exit;
}
return $payload;
}