addError($arg, '应用ID不能为空'); return; } if (!isset($authData['auth_type']) || empty($authData['auth_type'])) { $this->addError($arg, '认证类型不能为空'); return; } // 验证认证类型 $authType = $authData['auth_type']; $validAuthTypes = array_column(AUTH_TYPE::cases(), 'value'); if (!in_array($authType, $validAuthTypes)) { $this->addError($arg, '无效的认证类型'); return; } // 根据认证类型验证相应的认证信息 switch ($authType) { case AUTH_TYPE::API_KEY->value: $this->validateApiKeyAuth($authData, $arg); break; case AUTH_TYPE::OAUTH2->value: $this->validateOAuth2Auth($authData, $arg); break; case AUTH_TYPE::JWT->value: $this->validateJwtAuth($authData, $arg); break; case AUTH_TYPE::SIGNATURE->value: $this->validateSignatureAuth($authData, $arg); break; case AUTH_TYPE::BASIC->value: $this->validateBasicAuth($authData, $arg); break; case AUTH_TYPE::BEARER->value: $this->validateBearerAuth($authData, $arg); break; } } /** * 验证API Key认证 * * @param array $authData * @param string $arg * @return void */ protected function validateApiKeyAuth(array $authData, string $arg): void { if (!isset($authData['app_secret']) || empty($authData['app_secret'])) { $this->addError($arg, 'API密钥不能为空'); return; } $appId = $authData['app_id']; $appSecret = $authData['app_secret']; // 验证应用ID格式 if (strlen($appId) !== 32 || !ctype_alnum($appId)) { $this->addError($arg, '应用ID格式错误'); return; } // 验证应用密钥格式 if (strlen($appSecret) !== 64 || !ctype_alnum($appSecret)) { $this->addError($arg, '应用密钥格式错误'); return; } // 验证应用是否存在且有效 $app = OpenApiApp::where('app_id', $appId)->first(); if (!$app) { $this->addError($arg, '应用不存在'); return; } if ($app->app_secret !== $appSecret) { $this->addError($arg, '应用密钥错误'); return; } if (!$app->isActive()) { $this->addError($arg, '应用未激活或已被禁用'); return; } } /** * 验证OAuth2认证 * * @param array $authData * @param string $arg * @return void */ protected function validateOAuth2Auth(array $authData, string $arg): void { if (!isset($authData['access_token']) || empty($authData['access_token'])) { $this->addError($arg, '访问令牌不能为空'); return; } $accessToken = $authData['access_token']; // 验证访问令牌格式(这里简化处理,实际应该调用OAuth服务验证) if (strlen($accessToken) < 32) { $this->addError($arg, '访问令牌格式错误'); return; } // TODO: 调用OAuth模块验证令牌有效性 // $oauthService = app(OAuthService::class); // if (!$oauthService->validateToken($accessToken)) { // $this->addError($arg, '访问令牌无效或已过期'); // return; // } } /** * 验证JWT认证 * * @param array $authData * @param string $arg * @return void */ protected function validateJwtAuth(array $authData, string $arg): void { if (!isset($authData['token']) || empty($authData['token'])) { $this->addError($arg, 'JWT令牌不能为空'); return; } $token = $authData['token']; // 验证JWT令牌格式 $parts = explode('.', $token); if (count($parts) !== 3) { $this->addError($arg, 'JWT令牌格式错误'); return; } try { // 验证JWT令牌(这里简化处理,实际应该使用JWT库验证) foreach ($parts as $part) { $decoded = base64_decode($part, true); if ($decoded === false) { $this->addError($arg, 'JWT令牌格式错误'); return; } } // TODO: 使用JWT库验证令牌签名和有效期 // $jwt = app(JWTService::class); // if (!$jwt->validate($token)) { // $this->addError($arg, 'JWT令牌无效或已过期'); // return; // } } catch (\Exception $e) { $this->addError($arg, 'JWT令牌验证失败'); } } /** * 验证签名认证 * * @param array $authData * @param string $arg * @return void */ protected function validateSignatureAuth(array $authData, string $arg): void { $requiredFields = ['timestamp', 'nonce', 'signature']; foreach ($requiredFields as $field) { if (!isset($authData[$field]) || empty($authData[$field])) { $this->addError($arg, "缺少必需的签名参数: {$field}"); return; } } $timestamp = $authData['timestamp']; $nonce = $authData['nonce']; $signature = $authData['signature']; // 验证时间戳 if (!is_numeric($timestamp)) { $this->addError($arg, '时间戳格式错误'); return; } // 检查时间戳是否在合理范围内(5分钟内) $currentTime = time(); $timeDiff = abs($currentTime - $timestamp); if ($timeDiff > 300) { $this->addError($arg, '请求时间戳过期'); return; } // 验证随机数 if (strlen($nonce) < 8) { $this->addError($arg, '随机数长度不足'); return; } // 验证签名格式 if (strlen($signature) !== 64 || !ctype_xdigit($signature)) { $this->addError($arg, '签名格式错误'); return; } // TODO: 验证签名正确性 // $app = OpenApiApp::where('app_id', $authData['app_id'])->first(); // if ($app) { // $expectedSignature = $this->generateSignature($authData, $app->app_secret); // if (!hash_equals($expectedSignature, $signature)) { // $this->addError($arg, '签名验证失败'); // return; // } // } } /** * 验证Basic认证 * * @param array $authData * @param string $arg * @return void */ protected function validateBasicAuth(array $authData, string $arg): void { if (!isset($authData['username']) || empty($authData['username'])) { $this->addError($arg, '用户名不能为空'); return; } if (!isset($authData['password']) || empty($authData['password'])) { $this->addError($arg, '密码不能为空'); return; } $username = $authData['username']; $password = $authData['password']; // 验证用户名格式(应该是应用ID) if (strlen($username) !== 32 || !ctype_alnum($username)) { $this->addError($arg, '用户名格式错误'); return; } // 验证密码格式(应该是应用密钥) if (strlen($password) !== 64 || !ctype_alnum($password)) { $this->addError($arg, '密码格式错误'); return; } // 验证应用信息 $app = OpenApiApp::where('app_id', $username)->first(); if (!$app) { $this->addError($arg, '应用不存在'); return; } if ($app->app_secret !== $password) { $this->addError($arg, '认证失败'); return; } if (!$app->isActive()) { $this->addError($arg, '应用未激活或已被禁用'); return; } } /** * 验证Bearer认证 * * @param array $authData * @param string $arg * @return void */ protected function validateBearerAuth(array $authData, string $arg): void { if (!isset($authData['token']) || empty($authData['token'])) { $this->addError($arg, 'Bearer令牌不能为空'); return; } $token = $authData['token']; // 验证令牌格式 if (strlen($token) < 32) { $this->addError($arg, 'Bearer令牌格式错误'); return; } // TODO: 验证令牌有效性 // 这里可以根据实际需求验证令牌是否有效 // 可能需要查询数据库或调用其他服务 } /** * 验证应用状态 * * @param OpenApiApp $app * @param string $arg * @return void */ public function validateAppStatus(OpenApiApp $app, string $arg): void { if (!$app->isActive()) { $this->addError($arg, '应用未激活或已被禁用'); return; } if ($app->isExpired()) { $this->addError($arg, '应用已过期'); return; } if ($app->isSuspended()) { $this->addError($arg, '应用已被暂停'); return; } } /** * 验证权限范围 * * @param OpenApiApp $app * @param string $requiredScope * @param string $arg * @return void */ public function validateScope(OpenApiApp $app, string $requiredScope, string $arg): void { $appScopes = $app->scopes ?? []; if (empty($appScopes)) { $this->addError($arg, '应用没有配置权限范围'); return; } // 检查是否有管理员权限 if (in_array('ADMIN', $appScopes) || in_array('*', $appScopes)) { return; } // 检查是否有所需权限 if (!in_array($requiredScope, $appScopes)) { $this->addError($arg, "缺少必需的权限范围: {$requiredScope}"); return; } } }