JWT
Module JWT cung cấp API đơn giản để tạo và xác thực JSON Web Token, hỗ trợ các thuật toán HMAC (HS256/384/512) và RSA (RS256/384/512).
Encode token
use Vietiso\Core\JWT\JWT;
$payload = [
'sub' => $user->id,
'name' => $user->name,
'exp' => time() + 3600, // hết hạn sau 1 giờ
'nbf' => time(), // chưa có hiệu lực trước thời điểm này
];
$token = JWT::encode($payload, 'secret-key', 'HS256');
Decode token
try {
$payload = JWT::decode($token, 'secret-key', ['HS256']);
$userId = $payload['sub'];
} catch (\Vietiso\Core\JWT\Exception\ExpiredException $e) {
// Token đã hết hạn
} catch (\Vietiso\Core\JWT\Exception\SignatureException $e) {
// Chữ ký không hợp lệ
} catch (\Vietiso\Core\JWT\Exception\InvalidTokenException $e) {
// Token sai định dạng, thuật toán không được phép, hoặc chưa có hiệu lực
}
Leeway (dung sai thời gian)
Tham số $leeway (giây) cho phép bù trừ sai số đồng hồ giữa các server:
$payload = JWT::decode($token, 'secret-key', ['HS256'], leeway: 30);
Thuật toán hỗ trợ
| Hằng số | Loại | Hash |
|---|---|---|
HS256 | HMAC | SHA-256 |
HS384 | HMAC | SHA-384 |
HS512 | HMAC | SHA-512 |
RS256 | RSA | SHA-256 |
RS384 | RSA | SHA-384 |
RS512 | RSA | SHA-512 |
RSA (khóa bất đối xứng)
Với thuật toán RSA, $key khi encode là private key, khi decode là public key:
$privateKey = file_get_contents('/path/to/private.pem');
$publicKey = file_get_contents('/path/to/public.pem');
// Tạo token
$token = JWT::encode($payload, $privateKey, 'RS256');
// Xác thực token
$payload = JWT::decode($token, $publicKey, ['RS256']);
Payload claims
| Claim | Ý nghĩa |
|---|---|
exp | Thời điểm hết hạn (Unix timestamp). Nếu có, token sẽ bị từ chối sau thời điểm này. |
nbf | Not Before — thời điểm bắt đầu có hiệu lực. Nếu có, token bị từ chối trước thời điểm này. |
Các claim còn lại là tùy ý và được trả về nguyên vẹn khi decode.
Exceptions
| Exception | Khi nào ném |
|---|---|
InvalidTokenException | Token sai định dạng, thuật toán không nằm trong danh sách cho phép, hoặc chưa đến nbf |
SignatureException | Chữ ký không khớp |
ExpiredException | Token đã vượt quá exp |
Tất cả đều kế thừa Vietiso\Core\JWT\Exception\JWTException (extends RuntimeException), nên có thể catch chung:
try {
$payload = JWT::decode($token, $key, ['HS256']);
} catch (\Vietiso\Core\JWT\Exception\JWTException $e) {
// Xử lý mọi lỗi JWT tại đây
}