secret = $config['secret']; $this->algo = $config['algo']; $this->expiration = $config['expiration'] ?? 3600; $this->leeway = $config['leeway'] ?? 60; JWT::$leeway = $this->leeway; } public function encode(array $payload): string { $now = time(); $payload = array_merge([ 'iat' => $now, 'exp' => $now + $this->expiration, ], $payload); return JWT::encode($payload, $this->secret, $this->algo); } public function decode(string $token): ?array { try { $decoded = JWT::decode($token, new Key($this->secret, $this->algo)); return (array) $decoded; } catch (ExpiredException $e) { // Token expired return null; } catch (DomainException | UnexpectedValueException $e) { // Invalid token return null; } } public function refresh(string $token): ?string { $payload = $this->decode($token); if (!$payload) { return null; } unset($payload['iat'], $payload['exp'], $payload['nbf']); return $this->encode($payload); } }