API接口-authtoken、redis

This commit is contained in:
2026-03-19 18:07:18 +08:00
parent 019b536a89
commit 4f61c9d7fc
11 changed files with 303 additions and 3 deletions

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace app\common\library;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
use Firebase\JWT\SignatureInvalidException;
/**
* Agent 鉴权 JWT 工具
*/
class AgentJwt
{
public const ALG = 'HS256';
/**
* 生成 JWT authtoken
* @param array $payload agent_id, channel_id, admin_id 等
* @param int $expire 有效期(秒)
*/
public static function encode(array $payload, int $expire = 86400): string
{
$now = time();
$payload['iat'] = $now;
$payload['exp'] = $now + $expire;
$secret = self::getSecret();
return JWT::encode($payload, $secret, self::ALG);
}
/**
* 解析并验证 JWT返回 payload
* @return array payload失败返回空数组
*/
public static function decode(string $token): array
{
if ($token === '') {
return [];
}
try {
$secret = self::getSecret();
$decoded = JWT::decode($token, new Key($secret, self::ALG));
return (array) $decoded;
} catch (ExpiredException|SignatureInvalidException|\Throwable) {
return [];
}
}
/**
* 验证 JWT 是否有效
*/
public static function verify(string $token): bool
{
return !empty(self::decode($token));
}
private static function getSecret(): string
{
$secret = config('buildadmin.agent_auth.jwt_secret', '');
if ($secret === '') {
$secret = config('buildadmin.token.key', '');
}
return $secret;
}
}

View File

@@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
namespace app\common\library\token\driver;
use app\common\library\token\Driver;
use support\Redis as RedisConnection;
/**
* Token Redis 驱动(提升鉴权接口等高频调用的性能)
* @see Driver
*/
class Redis extends Driver
{
protected array $options = [];
public function __construct(array $options = [])
{
$this->options = array_merge([
'prefix' => 'tk:',
'expire' => 2592000,
], $options);
$this->handler = RedisConnection::connection('default');
}
public function set(string $token, string $type, int $userId, ?int $expire = null): bool
{
if ($expire === null) {
$expire = $this->options['expire'] ?? 2592000;
}
$expireTime = $expire !== 0 ? time() + $expire : 0;
$key = $this->getKey($token);
$data = [
'token' => $token,
'type' => $type,
'user_id' => $userId,
'create_time' => time(),
'expire_time' => $expireTime,
];
$ttl = $expire !== 0 ? $expire : 365 * 86400;
$this->handler->setEx($key, $ttl, json_encode($data));
return true;
}
public function get(string $token): array
{
$key = $this->getKey($token);
$raw = $this->handler->get($key);
if ($raw === false || $raw === null) {
return [];
}
$data = json_decode($raw, true);
if (!is_array($data)) {
return [];
}
$data['expires_in'] = $this->getExpiredIn($data['expire_time'] ?? 0);
return $data;
}
public function check(string $token, string $type, int $userId): bool
{
$data = $this->get($token);
if (!$data || ($data['expire_time'] && $data['expire_time'] <= time())) {
return false;
}
return $data['type'] === $type && (int) $data['user_id'] === $userId;
}
public function delete(string $token): bool
{
$this->handler->del($this->getKey($token));
return true;
}
public function clear(string $type, int $userId): bool
{
$pattern = $this->options['prefix'] . '*';
$keys = $this->handler->keys($pattern);
foreach ($keys as $key) {
$raw = $this->handler->get($key);
if ($raw !== false && $raw !== null) {
$data = json_decode($raw, true);
if (is_array($data) && ($data['type'] ?? '') === $type && (int) ($data['user_id'] ?? 0) === $userId) {
$this->handler->del($key);
}
}
}
return true;
}
private function getKey(string $token): string
{
return $this->options['prefix'] . $this->getEncryptedToken($token);
}
}