CallApiService.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <?php
  2. namespace App\Services;
  3. use App\Exceptions\ApiException;
  4. use App\Helpers\Utils;
  5. use DeviceDetector\ClientHints;
  6. use DeviceDetector\DeviceDetector;
  7. use Exception;
  8. use Unirest\Request;
  9. class CallApiService
  10. {
  11. const GATE_TOKEN_NOTFOUND = 505;
  12. public function callAppApi($request, $token, $appName)
  13. {
  14. if (empty($appName)) {
  15. $request['headers'] = ['GateToken' => $token];
  16. return $this->callApi($request);
  17. } else {
  18. $request['url'] = $token['ApiUrl'] . '/' .$request['url'];
  19. $request['headers'] = ['GateToken' => $token['GateToken']];
  20. $request['type'] = 'custom';
  21. return $this->callApi($request);
  22. }
  23. }
  24. public function callApi($request, $isAjax = false)
  25. {
  26. $type = $request['type'] ?? 'main';
  27. try {
  28. $response = Request::post(
  29. $this->buildUrl($request['url'], $type, $request['strong_type'] ?? null),
  30. $this->buildHeader($request['headers'] ?? [], $type),
  31. $this->buildQuery($request['data'], $request['url'])
  32. );
  33. } catch (Exception $e) {
  34. // gate-token-get api 는 에러떠도 넘어감
  35. // if ($request['url'] === 'gate-token-get') {
  36. // return '';
  37. // }
  38. return $this->errorResponse([
  39. 'apiStatus' => 503,
  40. 'body' => $e->getMessage()
  41. ], $isAjax);
  42. }
  43. if ($response->code == 200) {
  44. // return $this->errorResponse([
  45. // 'apiStatus' => 506,
  46. // 'body' => 'ㅁㄴㅁㄴ'
  47. // ], $isAjax);
  48. session()->put('_firstSendAPI', true);
  49. $data = json_encode($response->body ?? []);
  50. return json_decode($data, true);
  51. } else {
  52. return $this->errorResponse([
  53. 'apiStatus' => $response->code,
  54. 'body' => $response->body
  55. ], $isAjax);
  56. }
  57. }
  58. private function errorResponse($e, $isAjax): array
  59. {
  60. // if (! $isAjax) {
  61. if ($isAjax) {
  62. return ['apiStatus' => $e['apiStatus'], 'body' => $e['body']];
  63. }
  64. if ($e['apiStatus'] === 503 || $e['apiStatus'] === 505 || $e['apiStatus'] === 506 ||
  65. $e['apiStatus'] === 600 || $e['apiStatus'] === 0) {
  66. throw new ApiException($e['body'], $e['apiStatus']);
  67. } else {
  68. // notify()->error($e['body'], 'status code: '.$e['apiStatus'], 'bottomRight');
  69. return ['apiStatus' => $e['apiStatus'], 'body' => $e['body']];
  70. }
  71. }
  72. private function buildUrl($url, $type, $strongType): string
  73. {
  74. if ($type === 'custom') {
  75. return $url;
  76. } else if ($strongType) {
  77. return env('STRONG_' . strtoupper($strongType) . '_API_URL') . '/' . $url;
  78. }
  79. return config("app.api.{$type}.url") . $url;
  80. }
  81. public function getHeader($gateToken = null): array
  82. {
  83. $headers = $this->basicHeader();
  84. if ($gateToken) {
  85. $headers['GateToken'] = $gateToken;
  86. }
  87. return $headers;
  88. }
  89. public function basicHeader(): array
  90. {
  91. $userAgent = request()->header('User-Agent');
  92. $osStartPos = strpos($userAgent, "(") + 1;
  93. $osEndPos = strpos($userAgent, ")");
  94. $osString = substr($userAgent, $osStartPos, $osEndPos - $osStartPos);
  95. $result = [
  96. 'Content-Type' => 'application/json',
  97. 'FrontendHost' => url('/'),
  98. 'RemoteIp' => request()->ip(),
  99. 'Referer' => rtrim(request()->headers->get('referer'), '/'),
  100. 'DeviceDesc' => $osString,
  101. 'AppType' => $this->getAppType(),
  102. ];
  103. if (! session()->get('_firstSendAPI')) {
  104. $result = array_merge($result, ['PageTime' => now()->timestamp ]);
  105. }
  106. return $result;
  107. }
  108. private function buildHeader($headers, $type): array
  109. {
  110. if (empty($headers)) {
  111. if ($type === 'custom') {
  112. $type = 'main';
  113. }
  114. return array_merge($this->basicHeader(), ['GateToken' => session('GateToken')[$type]]);
  115. }
  116. return $headers;
  117. }
  118. private function buildQuery($query, $url)
  119. {
  120. // return Body::json($query);
  121. if (\Str::contains($url, '-act')) {
  122. $query['Page'][0]['Ip'] = "";
  123. }
  124. return json_encode($query, JSON_UNESCAPED_UNICODE);
  125. }
  126. private function getAppType(): string
  127. {
  128. if (request()->header('X-Requested-With') === 'XMLHttpRequest') {
  129. return 'js';
  130. } else {
  131. return 'web';
  132. }
  133. }
  134. public function getGateToken($query, $type)
  135. {
  136. return $this->callApi([
  137. 'url' => 'gate-token-get',
  138. 'data' => $query,
  139. 'headers' => $this->basicHeader(),
  140. 'type' => $type
  141. ]);
  142. }
  143. public function setGateToken(): bool
  144. {
  145. $result = false;
  146. session()->forget('GateToken');
  147. foreach (config('app.api') as $type => $value) {
  148. $query = [
  149. 'ClientId' => config("app.api.{$type}.ClientId"),
  150. 'BeforeBase64' => config("app.api.{$type}.BeforeBase64"),
  151. 'AppBase64' => ''
  152. // 'BeforeBase64' => base64_encode(sodium_crypto_box_seal(json_encode(config("app.api.{$type}.decrypted")),
  153. // base64_decode(config("app.api.{$type}.public_key")))),
  154. ];
  155. if (empty($query['ClientId']) || empty($query['BeforeBase64'])) { continue; }
  156. $response = $this->getGateToken($query, $type);
  157. if (isset($response['GateToken']) && $gateToken = $response['GateToken']) {
  158. session()->put("GateToken.{$type}", $gateToken);
  159. $result = true;
  160. }
  161. }
  162. return $result;
  163. }
  164. public function verifyApiError($response): bool
  165. {
  166. return isset($response['apiStatus']);
  167. }
  168. public function getData(\Illuminate\Http\Request $request)
  169. {
  170. if ($request['is_user_page'] && empty(session('user'))) {
  171. return ['apiStatus' => 555, 'body' => 'User session not found'];
  172. }
  173. if ($request['encode_status']) {
  174. $request['data'] = json_decode($request['data']);
  175. }
  176. // if ($request['strong_type']) {
  177. // $request['url'] = env('STRONG_' . strtoupper($request['strong_type']) . '_API_URL') . '/' . $request['url'];
  178. // $request['type'] = 'custom';
  179. // }
  180. $response = $this->callApi([
  181. 'url' => $request['url'],
  182. 'data' => $request['data'],
  183. 'headers' => $request['headers'],
  184. 'type' => $request['type'],
  185. 'strong_type' => $request['strong_type']
  186. ], true);
  187. if ($request['para_cache'] && ! isset($response['apiStatus'])) {
  188. Utils::putParamCache($request['para_cache'], $request['url'], json_encode($request['data']));
  189. }
  190. return $response;
  191. }
  192. }