Files

64 lines
1.8 KiB
PHP

<?php
namespace WorkbloomERP\Security;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Throwable;
use RuntimeException;
class JwtService {
private string $secret;
private int $expiresIn;
public function __construct(?string $secret = null, ?int $expiresIn = null) {
$this->secret = $secret ?? $_ENV['JWT_SECRET'] ?? getenv('JWT_SECRET') ?: '';
if (empty($this->secret)) {
throw new RuntimeException('JWT secret is not configured.');
}
$this->expiresIn = $expiresIn ?? (int)($_ENV['JWT_EXPIRES_IN'] ?? getenv('JWT_EXPIRES_IN') ?: 86400);
}
/**
* Gera um novo token JWT para o payload fornecido.
*
* @param array $userData Dados do usuário e contexto
* @return array{token: string, expires_in: int, expires_at: int}
*/
public function generateToken(array $userData): array {
$now = time();
$expiresAt = $now + $this->expiresIn;
$payload = array_merge($userData, [
'iat' => $now,
'nbf' => $now,
'exp' => $expiresAt,
]);
$token = JWT::encode($payload, $this->secret, 'HS256');
return [
'token' => $token,
'expires_in' => $this->expiresIn,
'expires_at' => $expiresAt,
];
}
/**
* Decodifica e valida o token JWT.
* Retorna o payload em array ou lança uma exceção caso inválido ou expirado.
*
* @param string $token
* @return array
* @throws RuntimeException
*/
public function validateToken(string $token): array {
try {
$decoded = JWT::decode($token, new Key($this->secret, 'HS256'));
return (array)$decoded;
} catch (Throwable $e) {
throw new RuntimeException('Token inválido ou expirado: ' . $e->getMessage(), 401, $e);
}
}
}