diff --git a/backend/app/Middleware/AuthMiddleware.php b/backend/app/Middleware/AuthMiddleware.php index 0fb6c16..97003fb 100644 --- a/backend/app/Middleware/AuthMiddleware.php +++ b/backend/app/Middleware/AuthMiddleware.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Middleware; +use App\Model\ApiKey; +use App\Model\User; use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -21,9 +23,32 @@ class AuthMiddleware implements MiddlewareInterface } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + // 1. 尝试 JWT Bearer Token 认证 + $bearer_token = $this->extractBearerToken($request); + if ($bearer_token !== null) { + return $this->authenticateByJwt($request, $handler); + } + + // 2. 尝试 API Key 认证 + $api_key = $request->getHeaderLine('X-API-Key'); + if ($api_key !== '') { + return $this->authenticateByApiKey($api_key, $request, $handler); + } + + // 3. 无认证凭据 + return $this->response->json([ + 'code' => 401, + 'message' => '未授权,请先登录', + ])->withStatus(401); + } + + /** + * JWT Token 认证 + */ + protected function authenticateByJwt(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { try { - // 验证 token $user = $this->auth->guard('jwt')->user(); if (!$user) { @@ -33,9 +58,8 @@ class AuthMiddleware implements MiddlewareInterface ])->withStatus(401); } - // @attention check here! // 检查用户状态 - if (method_exists($user, '__get') && $user->status !== 1) { + if ($user instanceof User && $user->status !== 1) { return $this->response->json([ 'code' => 403, 'message' => '账号已被禁用', @@ -55,4 +79,52 @@ class AuthMiddleware implements MiddlewareInterface return $handler->handle($request); } + + /** + * API Key 认证 + */ + protected function authenticateByApiKey(string $plain_key, ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $api_key = ApiKey::findByPlainKey($plain_key); + + if (!$api_key) { + return $this->response->json([ + 'code' => 401, + 'message' => 'API Key 无效或已过期', + ])->withStatus(401); + } + + $user = $api_key->user; + + if (!$user || $user->status !== 1) { + return $this->response->json([ + 'code' => 403, + 'message' => '账号已被禁用', + ])->withStatus(403); + } + + // 更新最后使用时间 + $api_key->last_used_at = \Carbon\Carbon::now(); + $api_key->save(); + + // 通过 JWT guard 登录用户,使后续代码可通过 auth->guard('jwt')->user() 获取用户 + $this->auth->guard('jwt')->login($user); + + return $handler->handle($request); + } + + /** + * 从请求头提取 Bearer Token + */ + protected function extractBearerToken(ServerRequestInterface $request): ?string + { + $header = $request->getHeaderLine('Authorization'); + + if ($header !== '' && str_starts_with($header, 'Bearer ')) { + $token = substr($header, 7); + return $token !== '' ? $token : null; + } + + return null; + } }