From 5ab16243bda6bba529923be950e234b6c6e6e8c6 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Thu, 5 Mar 2026 13:44:56 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=AE=BE=E8=AE=A1=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E7=A0=81=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/AuthTokenController.php | 12 ++++----- server/app/api/controller/GameController.php | 12 ++++----- server/app/api/controller/UserController.php | 10 +++---- .../middleware/CheckAuthTokenMiddleware.php | 14 +++++----- .../middleware/CheckUserTokenMiddleware.php | 4 +-- server/app/api/util/ReturnCode.php | 27 ++++++++++++++----- 6 files changed, 46 insertions(+), 33 deletions(-) diff --git a/server/app/api/controller/AuthTokenController.php b/server/app/api/controller/AuthTokenController.php index 92384bb..a78dcc8 100644 --- a/server/app/api/controller/AuthTokenController.php +++ b/server/app/api/controller/AuthTokenController.php @@ -25,7 +25,7 @@ class AuthTokenController extends OpenController public function index(Request $request): Response { if (strtoupper($request->method()) !== 'GET') { - return $this->fail('仅支持 GET 请求', ReturnCode::EMPTY_PARAMS); + return $this->fail('仅支持 GET 请求', ReturnCode::PARAMS_ERROR); } $param = $request->get(); @@ -35,27 +35,27 @@ class AuthTokenController extends OpenController $time = trim((string) ($param['time'] ?? '')); if ($signature === '' || $secret === '' || $device === '' || $time === '') { - return $this->fail('signature、secret、device、time 均为必传且不能为空', ReturnCode::EMPTY_PARAMS); + return $this->fail('signature、secret、device、time 均为必传且不能为空', ReturnCode::PARAMS_ERROR); } $serverSecret = trim((string) config('api.auth_token_secret', '')); if ($serverSecret === '') { - return $this->fail('服务未配置 API_AUTH_TOKEN_SECRET', ReturnCode::EMPTY_PARAMS); + return $this->fail('服务未配置 API_AUTH_TOKEN_SECRET', ReturnCode::PARAMS_ERROR); } if ($secret !== $serverSecret) { - return $this->fail('密钥错误', ReturnCode::EMPTY_PARAMS); + return $this->fail('密钥错误', ReturnCode::FORBIDDEN); } $tolerance = (int) config('api.auth_token_time_tolerance', 300); $now = time(); $ts = is_numeric($time) ? (int) $time : 0; if ($ts <= 0 || abs($now - $ts) > $tolerance) { - return $this->fail('时间戳无效或已过期', ReturnCode::EMPTY_PARAMS); + return $this->fail('时间戳无效或已过期', ReturnCode::PARAMS_ERROR); } $sign = $this->getAuthToken($device, $serverSecret, $time); if ($sign !== $signature) { - return $this->fail('签名验证失败', ReturnCode::EMPTY_PARAMS); + return $this->fail('签名验证失败', ReturnCode::FORBIDDEN); } $exp = (int) config('api.auth_token_exp', 86400); diff --git a/server/app/api/controller/GameController.php b/server/app/api/controller/GameController.php index ef6bd5d..e71ba8d 100644 --- a/server/app/api/controller/GameController.php +++ b/server/app/api/controller/GameController.php @@ -31,7 +31,7 @@ class GameController extends OpenController $userId = UserLogic::getUserIdFromRequest($request) ?? 0; $count = (int) $request->post('count', 0); if (!in_array($count, [1, 5, 10], true)) { - return $this->fail('购买抽奖券错误', ReturnCode::EMPTY_PARAMS); + return $this->fail('购买抽奖券错误', ReturnCode::PARAMS_ERROR); } try { @@ -45,7 +45,7 @@ class GameController extends OpenController $coin = $player ? (float) $player->coin : 0; return $this->success(['coin' => $coin], $msg); } - return $this->fail($msg, ReturnCode::EMPTY_PARAMS); + return $this->fail($msg, ReturnCode::BUSINESS_ERROR); } } @@ -72,16 +72,16 @@ class GameController extends OpenController $userId = UserLogic::getUserIdFromRequest($request) ?? 0; $rediction = $request->post('rediction'); if ($rediction === '' || $rediction === null) { - return $this->fail('请传递 rediction 参数', ReturnCode::EMPTY_PARAMS); + return $this->fail('请传递 rediction 参数', ReturnCode::PARAMS_ERROR); } $direction = (int) $rediction; if (!in_array($direction, [0, 1], true)) { - return $this->fail('rediction 必须为 0 或 1', ReturnCode::EMPTY_PARAMS); + return $this->fail('rediction 必须为 0 或 1', ReturnCode::PARAMS_ERROR); } $player = DicePlayer::find($userId); if (!$player) { - return $this->fail('用户不存在', ReturnCode::EMPTY_PARAMS); + return $this->fail('用户不存在', ReturnCode::NOT_FOUND); } $minEv = (float) DiceRewardConfig::min('real_ev'); $minCoin = abs($minEv + 100); @@ -95,7 +95,7 @@ class GameController extends OpenController $data = $logic->run($userId, $direction); return $this->success($data); } catch (ApiException $e) { - return $this->fail($e->getMessage(), ReturnCode::EMPTY_PARAMS); + return $this->fail($e->getMessage(), ReturnCode::BUSINESS_ERROR); } catch (\Throwable $e) { $timeoutRecord = null; try { diff --git a/server/app/api/controller/UserController.php b/server/app/api/controller/UserController.php index 20b4782..acd5ab9 100644 --- a/server/app/api/controller/UserController.php +++ b/server/app/api/controller/UserController.php @@ -28,7 +28,7 @@ class UserController extends OpenController $phone = $request->post('phone', ''); $password = $request->post('password', ''); if ($phone === '' || $password === '') { - return $this->fail('请填写手机号和密码', ReturnCode::EMPTY_PARAMS); + return $this->fail('请填写手机号和密码', ReturnCode::PARAMS_ERROR); } $logic = new UserLogic(); $data = $logic->login($phone, $password); @@ -50,7 +50,7 @@ class UserController extends OpenController $password = $request->post('password', ''); $nickname = $request->post('nickname'); if ($phone === '' || $password === '') { - return $this->fail('请填写手机号和密码', ReturnCode::EMPTY_PARAMS); + return $this->fail('请填写手机号和密码', ReturnCode::PARAMS_ERROR); } $logic = new UserLogic(); $data = $logic->register($phone, $password, $nickname ? (string) $nickname : null); @@ -70,7 +70,7 @@ class UserController extends OpenController { $token = $request->userToken ?? UserLogic::getTokenFromRequest($request); if ($token === '' || !UserLogic::logout($token)) { - return $this->fail('退出失败或 token 已失效', ReturnCode::TOKEN_TIMEOUT); + return $this->fail('退出失败或 token 已失效', ReturnCode::TOKEN_INVALID); } return $this->success('已退出登录'); } @@ -86,7 +86,7 @@ class UserController extends OpenController $userId = UserLogic::getUserIdFromRequest($request) ?? 0; $user = UserLogic::getCachedUser($userId); if (empty($user)) { - return $this->fail('用户不存在', ReturnCode::EMPTY_PARAMS); + return $this->fail('用户不存在', ReturnCode::NOT_FOUND); } $fields = ['id', 'username', 'phone', 'uid', 'name', 'coin', 'total_draw_count']; $info = []; @@ -108,7 +108,7 @@ class UserController extends OpenController $userId = UserLogic::getUserIdFromRequest($request) ?? 0; $user = UserLogic::getCachedUser($userId); if (empty($user)) { - return $this->fail('用户不存在', ReturnCode::EMPTY_PARAMS); + return $this->fail('用户不存在', ReturnCode::NOT_FOUND); } $coin = $user['coin'] ?? 0; if (is_string($coin) && is_numeric($coin)) { diff --git a/server/app/api/middleware/CheckAuthTokenMiddleware.php b/server/app/api/middleware/CheckAuthTokenMiddleware.php index efd5df6..3c33ec1 100644 --- a/server/app/api/middleware/CheckAuthTokenMiddleware.php +++ b/server/app/api/middleware/CheckAuthTokenMiddleware.php @@ -37,23 +37,23 @@ class CheckAuthTokenMiddleware implements MiddlewareInterface $token = $this->getAuthTokenFromRequest($request); if ($token === '') { - throw new ApiException('请携带 auth-token', ReturnCode::MISSING_TOKEN); + throw new ApiException('请携带 auth-token', ReturnCode::UNAUTHORIZED); } if (!$this->looksLikeJwt($token)) { - throw new ApiException('auth-token 格式无效', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException('auth-token 格式无效', ReturnCode::TOKEN_INVALID); } $decoded = $this->verifyAuthToken($token); $extend = $decoded['extend'] ?? []; if (($extend['plat'] ?? '') !== 'api') { - throw new ApiException('auth-token 无效(非 API 凭证)', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException('auth-token 无效(非 API 凭证)', ReturnCode::TOKEN_INVALID); } // 同一设备只允许一个 auth-token 生效,非当前 token 视为已失效 $device = (string) ($extend['device'] ?? ''); if ($device !== '' && !AuthTokenCache::isCurrentToken($device, $token)) { - throw new ApiException('auth-token 已失效(该设备已签发新凭证,请使用新 auth-token)', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException('auth-token 已失效(该设备已签发新凭证,请使用新 auth-token)', ReturnCode::TOKEN_INVALID); } return $handler($request); @@ -87,13 +87,13 @@ class CheckAuthTokenMiddleware implements MiddlewareInterface return JwtToken::verify(1, $token); } catch (JwtTokenExpiredException $e) { Log::error('auth-token 已过期, 报错信息' . $e); - throw new ApiException('auth-token 已过期', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException('auth-token 已过期', ReturnCode::TOKEN_INVALID); } catch (JwtTokenException $e) { Log::error('auth-token 无效, 报错信息' . $e); - throw new ApiException($e->getMessage() ?: 'auth-token 无效', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException($e->getMessage() ?: 'auth-token 无效', ReturnCode::TOKEN_INVALID); } catch (\Throwable $e) { Log::error('auth-token 校验失败, 报错信息' . $e); - throw new ApiException('auth-token 校验失败', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException('auth-token 校验失败', ReturnCode::TOKEN_INVALID); } } diff --git a/server/app/api/middleware/CheckUserTokenMiddleware.php b/server/app/api/middleware/CheckUserTokenMiddleware.php index 30d1a81..f7f4442 100644 --- a/server/app/api/middleware/CheckUserTokenMiddleware.php +++ b/server/app/api/middleware/CheckUserTokenMiddleware.php @@ -26,12 +26,12 @@ class CheckUserTokenMiddleware implements MiddlewareInterface } } if (empty($token)) { - throw new ApiException('请携带 user-token', ReturnCode::MISSING_TOKEN); + throw new ApiException('请携带 user-token', ReturnCode::UNAUTHORIZED); } $userId = UserLogic::getUserIdFromToken($token); if ($userId === null) { - throw new ApiException('user-token 无效或已过期', ReturnCode::TOKEN_TIMEOUT); + throw new ApiException('user-token 无效或已过期', ReturnCode::TOKEN_INVALID); } $request->user_id = $userId; diff --git a/server/app/api/util/ReturnCode.php b/server/app/api/util/ReturnCode.php index aba2a58..413a753 100644 --- a/server/app/api/util/ReturnCode.php +++ b/server/app/api/util/ReturnCode.php @@ -4,19 +4,32 @@ declare(strict_types=1); namespace app\api\util; /** - * API 状态码统一管理 + * API 统一状态码 + * 与 HTTP 语义对齐,便于前端与网关处理 */ class ReturnCode { /** 200 成功 */ public const SUCCESS = 200; - /** 201 请携带 token(auth-token / user-token) */ - public const MISSING_TOKEN = 201; + /** 400 请求参数错误(缺少参数、参数无效、格式错误等) */ + public const PARAMS_ERROR = 400; - /** 202 缺少参数 / 参数错误 / 业务校验不通过(如余额不足、购买抽奖券错误等) */ - public const EMPTY_PARAMS = 202; + /** 401 未授权(未携带 auth-token 或 user-token) */ + public const UNAUTHORIZED = 401; - /** 203 token 过期或无效(auth-token / user-token 过期、缓存已过期等) */ - public const TOKEN_TIMEOUT = 203; + /** 402 token 无效或已过期(格式无效、签名错误、过期、非当前有效 token 等) */ + public const TOKEN_INVALID = 402; + + /** 403 鉴权失败(密钥错误、签名验证失败等) */ + public const FORBIDDEN = 403; + + /** 404 资源不存在(用户不存在等) */ + public const NOT_FOUND = 404; + + /** 422 业务逻辑错误(余额不足、购买失败、业务校验不通过等) */ + public const BUSINESS_ERROR = 422; + + /** 500 服务器内部错误 */ + public const SERVER_ERROR = 500; }