From 74612f136e8e1db69f37150b479a9c6fe9382c92 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Thu, 5 Mar 2026 12:21:31 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=B8=E5=90=8C=E7=9A=84=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E6=A0=87=E8=AF=86dice=E5=8F=AA=E4=BF=9D=E8=AF=81=E4=B8=80?= =?UTF-8?q?=E4=B8=AAauth-token=E7=94=9F=E6=95=88=EF=BC=8C=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E6=8E=89=E5=A4=9A=E4=BD=99=E7=9A=84=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E4=B8=AAdice=E5=A4=9A=E4=BD=99=E7=9A=84auth-token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/app/api/cache/AuthTokenCache.php | 54 +++++++++++++++++++ .../api/controller/AuthTokenController.php | 6 ++- .../middleware/CheckAuthTokenMiddleware.php | 7 +++ server/config/api.php | 2 + 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 server/app/api/cache/AuthTokenCache.php diff --git a/server/app/api/cache/AuthTokenCache.php b/server/app/api/cache/AuthTokenCache.php new file mode 100644 index 0000000..7e1d28e --- /dev/null +++ b/server/app/api/cache/AuthTokenCache.php @@ -0,0 +1,54 @@ +fail('签名验证失败', ReturnCode::EMPTY_PARAMS); } - $exp = config('api.auth_token_exp', 86400); + $exp = (int) config('api.auth_token_exp', 86400); $tokenResult = JwtToken::generateToken([ 'id' => 0, 'plat' => 'api', @@ -65,6 +66,9 @@ class AuthTokenController extends OpenController 'access_exp' => $exp, ]); + // 同一设备只保留最新 token,覆盖后旧 token 失效 + AuthTokenCache::setDeviceToken($device, $tokenResult['access_token'], $exp); + return $this->success([ 'auth-token' => $tokenResult['access_token'], 'expires_in' => $tokenResult['expires_in'], diff --git a/server/app/api/middleware/CheckAuthTokenMiddleware.php b/server/app/api/middleware/CheckAuthTokenMiddleware.php index 72503a4..efd5df6 100644 --- a/server/app/api/middleware/CheckAuthTokenMiddleware.php +++ b/server/app/api/middleware/CheckAuthTokenMiddleware.php @@ -11,6 +11,7 @@ use Tinywan\Jwt\JwtToken; use Tinywan\Jwt\Exception\JwtTokenException; use Tinywan\Jwt\Exception\JwtTokenExpiredException; use app\api\util\ReturnCode; +use app\api\cache\AuthTokenCache; use plugin\saiadmin\exception\ApiException; /** @@ -49,6 +50,12 @@ class CheckAuthTokenMiddleware implements MiddlewareInterface throw new ApiException('auth-token 无效(非 API 凭证)', ReturnCode::TOKEN_TIMEOUT); } + // 同一设备只允许一个 auth-token 生效,非当前 token 视为已失效 + $device = (string) ($extend['device'] ?? ''); + if ($device !== '' && !AuthTokenCache::isCurrentToken($device, $token)) { + throw new ApiException('auth-token 已失效(该设备已签发新凭证,请使用新 auth-token)', ReturnCode::TOKEN_TIMEOUT); + } + return $handler($request); } diff --git a/server/config/api.php b/server/config/api.php index d8fe2c1..2792834 100644 --- a/server/config/api.php +++ b/server/config/api.php @@ -9,6 +9,8 @@ return [ 'auth_token_time_tolerance' => (int) env('API_AUTH_TOKEN_TIME_TOLERANCE', 300), // auth-token 有效期(秒),默认 24 小时 'auth_token_exp' => (int) env('API_AUTH_TOKEN_EXP', 86400), + // auth-token 按设备存储的 Redis key 前缀(同一设备只保留最新一个 auth-token) + 'auth_token_device_prefix' => env('API_AUTH_TOKEN_DEVICE_PREFIX', 'api:auth_token:'), // user-token 有效期(秒),默认 7 天 'user_token_exp' => (int) env('API_USER_TOKEN_EXP', 604800), // 用户信息 Redis 缓存过期时间(秒),默认 7 天