更新
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace app\service;
|
||||
|
||||
class JwtService
|
||||
{
|
||||
public static function generateToken(array $payload): string
|
||||
{
|
||||
$secret = config('jwt.secret');
|
||||
$expire = config('jwt.expire');
|
||||
|
||||
$header = self::base64UrlEncode(json_encode(['typ' => 'JWT', 'alg' => 'HS256']));
|
||||
$payload['exp'] = time() + $expire;
|
||||
$payload['iat'] = time();
|
||||
$body = self::base64UrlEncode(json_encode($payload));
|
||||
$signature = self::base64UrlEncode(hash_hmac('sha256', "{$header}.{$body}", $secret, true));
|
||||
|
||||
return "{$header}.{$body}.{$signature}";
|
||||
}
|
||||
|
||||
public static function verifyToken(?string $token): ?array
|
||||
{
|
||||
if (!$token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (str_starts_with($token, 'Bearer ')) {
|
||||
$token = substr($token, 7);
|
||||
}
|
||||
|
||||
$parts = explode('.', $token);
|
||||
if (count($parts) !== 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
[$header, $body, $signature] = $parts;
|
||||
$secret = config('jwt.secret');
|
||||
$expected = self::base64UrlEncode(hash_hmac('sha256', "{$header}.{$body}", $secret, true));
|
||||
|
||||
if (!hash_equals($expected, $signature)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = json_decode(self::base64UrlDecode($body), true);
|
||||
if (!$payload || ($payload['exp'] ?? 0) < time()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
private static function base64UrlEncode(string $data): string
|
||||
{
|
||||
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
|
||||
}
|
||||
|
||||
private static function base64UrlDecode(string $data): string
|
||||
{
|
||||
return base64_decode(strtr($data, '-_', '+/'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user