UrsLoginRequest.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. namespace ThirdParty\Urs\Request;
  3. use ThirdParty\Urs\Util\CryptoService;
  4. use Illuminate\Support\Facades\Log;
  5. /**
  6. * URS登录请求类
  7. *
  8. * 专门处理手机号+密码登录请求,遵循"一个Request类只完成一种请求"的原则
  9. * 根据手机号和密码获取用户ID和用户密钥
  10. */
  11. class UrsLoginRequest extends BaseRequest
  12. {
  13. /**
  14. * 处理登录请求
  15. *
  16. * @param array $params 请求参数,包含mobile和password字段
  17. * @return array 返回包含userId和userKey的数组
  18. * @throws \Exception
  19. */
  20. protected function handler(array $params = []): array
  21. {
  22. Log::info('URS登录请求开始', [
  23. 'params_keys' => array_keys($params),
  24. 'mobile' => $params['mobile'] ?? 'not_provided',
  25. 'has_password' => !empty($params['password'])
  26. ]);
  27. // 验证必需参数
  28. if (empty($params['mobile'])) {
  29. Log::error('URS登录请求参数验证失败', ['error' => 'mobile参数是必填的']);
  30. throw new \Exception('mobile参数是必填的');
  31. }
  32. if (empty($params['password'])) {
  33. Log::error('URS登录请求参数验证失败', ['error' => 'password参数是必填的']);
  34. throw new \Exception('password参数是必填的');
  35. }
  36. try {
  37. // 获取URS凭证
  38. $credential = $this->getUrsCredential();
  39. $apiUrl = $this->getService()->base_url; // 直接使用服务的base_url
  40. $appKey = $credential->getApiKey();
  41. $ecologyId = $credential->getEcologyId();
  42. Log::info('URS配置获取成功', [
  43. 'api_url' => $apiUrl,
  44. 'app_key_length' => strlen($appKey),
  45. 'ecology_id' => $ecologyId
  46. ]);
  47. if (empty($apiUrl) || empty($appKey)) {
  48. Log::error('URS配置验证失败', [
  49. 'api_url_empty' => empty($apiUrl),
  50. 'app_key_empty' => empty($appKey),
  51. 'api_url' => $apiUrl,
  52. 'app_key_length' => strlen($appKey)
  53. ]);
  54. throw new \Exception('URS配置不完整,缺少api_url或app_key');
  55. }
  56. // 准备请求数据
  57. $requestData = [
  58. 'mobile' => $params['mobile'],
  59. 'password' => $params['password']
  60. ];
  61. Log::info('请求数据准备完成', [
  62. 'mobile' => $requestData['mobile'],
  63. 'has_password' => !empty($requestData['password'])
  64. ]);
  65. // 使用URS加密服务加密请求数据
  66. $cryptoService = new CryptoService($appKey);
  67. $encryptedData = $cryptoService->encrypt($requestData);
  68. Log::info('请求数据加密完成', [
  69. 'encrypted_data_keys' => array_keys($encryptedData)
  70. ]);
  71. // 构建完整的API URL
  72. $fullUrl = rtrim($apiUrl, '/') . "/api/ecology/{$ecologyId}/login";
  73. Log::info('准备发送HTTP请求', [
  74. 'full_url' => $fullUrl
  75. ]);
  76. // 发送HTTP请求到URS
  77. $response = $this->sendHttpRequest($fullUrl, $encryptedData);
  78. Log::info('HTTP请求响应接收完成', [
  79. 'response_keys' => array_keys($response),
  80. 'has_encrypted_fields' => isset($response['data'], $response['iv'], $response['timestamp'], $response['sign'])
  81. ]);
  82. // 解密响应数据
  83. $decryptedResponse = $cryptoService->decrypt($response);
  84. Log::info('响应数据解密完成', [
  85. 'decrypted_keys' => array_keys($decryptedResponse),
  86. 'has_user_id' => isset($decryptedResponse['userId']),
  87. 'has_user_key' => isset($decryptedResponse['userKey'])
  88. ]);
  89. // 验证响应数据
  90. if (!isset($decryptedResponse['userId'])) {
  91. Log::error('URS登录响应数据验证失败', ['error' => '响应中缺少userId字段']);
  92. throw new \Exception('URS登录失败:响应中缺少userId字段');
  93. }
  94. if (!isset($decryptedResponse['userKey'])) {
  95. Log::error('URS登录响应数据验证失败', ['error' => '响应中缺少userKey字段']);
  96. throw new \Exception('URS登录失败:响应中缺少userKey字段');
  97. }
  98. Log::info('URS登录请求处理成功', [
  99. 'user_id' => $decryptedResponse['userId'],
  100. 'user_key_length' => strlen($decryptedResponse['userKey'])
  101. ]);
  102. return $decryptedResponse;
  103. } catch (\Exception $e) {
  104. Log::error('URS登录请求处理失败', [
  105. 'error' => $e->getMessage(),
  106. 'trace' => $e->getTraceAsString()
  107. ]);
  108. throw $e;
  109. }
  110. }
  111. /**
  112. * 发送HTTP请求
  113. *
  114. * @param string $url 请求URL
  115. * @param array $data 请求数据
  116. * @return array
  117. * @throws \Exception
  118. */
  119. protected function sendHttpRequest(string $url, array $data): array
  120. {
  121. // 记录请求开始日志
  122. Log::info('URS HTTP请求开始', [
  123. 'url' => $url,
  124. 'request_data_keys' => array_keys($data),
  125. 'request_data_size' => strlen(json_encode($data)),
  126. 'method' => 'POST'
  127. ]);
  128. $ch = curl_init();
  129. curl_setopt_array($ch, [
  130. CURLOPT_URL => $url,
  131. CURLOPT_POST => true,
  132. CURLOPT_POSTFIELDS => json_encode($data),
  133. CURLOPT_RETURNTRANSFER => true,
  134. CURLOPT_TIMEOUT => 30,
  135. CURLOPT_HTTPHEADER => [
  136. 'Content-Type: application/json',
  137. 'User-Agent: KKU-ThirdParty-URS/1.0',
  138. ],
  139. ]);
  140. $response = curl_exec($ch);
  141. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  142. $error = curl_error($ch);
  143. curl_close($ch);
  144. // 记录HTTP响应日志
  145. Log::info('URS HTTP请求完成', [
  146. 'http_code' => $httpCode,
  147. 'response_size' => strlen($response),
  148. 'has_error' => !empty($error)
  149. ]);
  150. if ($error) {
  151. Log::error('URS HTTP请求失败', ['curl_error' => $error]);
  152. throw new \Exception("HTTP请求失败: {$error}");
  153. }
  154. if ($httpCode !== 200) {
  155. Log::error('URS HTTP请求返回错误状态码', [
  156. 'http_code' => $httpCode,
  157. 'response' => $response
  158. ]);
  159. throw new \Exception("HTTP请求失败,状态码: {$httpCode}");
  160. }
  161. $decodedResponse = json_decode($response, true);
  162. if (json_last_error() !== JSON_ERROR_NONE) {
  163. Log::error('URS HTTP响应JSON解析失败', [
  164. 'json_error' => json_last_error_msg(),
  165. 'response' => $response
  166. ]);
  167. throw new \Exception('响应数据格式错误');
  168. }
  169. Log::info('URS HTTP请求响应解析成功', [
  170. 'response_keys' => array_keys($decodedResponse)
  171. ]);
  172. return $decodedResponse;
  173. }
  174. }