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 { $user = $this->auth->guard('jwt')->user(); if (!$user) { return $this->response->json([ 'code' => 401, 'message' => '未授权,请先登录', ])->withStatus(401); } // 检查用户状态 if ($user instanceof User && $user->status !== 1) { return $this->response->json([ 'code' => 403, 'message' => '账号已被禁用', ])->withStatus(403); } } catch (UnauthorizedException $e) { return $this->response->json([ 'code' => 401, 'message' => 'Token 无效或已过期', ])->withStatus(401); } catch (\Throwable $e) { return $this->response->json([ 'code' => 500, 'message' => '认证失败: ' . $e->getMessage(), ])->withStatus(500); } 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 登录用户,生成 token 并注入请求头,使后续代码可通过 auth->guard('jwt')->user() 获取用户 $token = $this->auth->guard('jwt')->login($user); $request = $request->withHeader('Authorization', 'Bearer ' . $token); // 将带 Authorization 头的新请求写回协程 Context,确保 JwtGuard 代理对象能读到 \Hyperf\Context\Context::set(ServerRequestInterface::class, $request); 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; } }