В настоящее время я создаю приложение финансового микросервиса с использованием микрофреймворка Laravel/Lumen. Все работает отлично, как и ожидалось. Моя проблема сейчас в том, что я пытаюсь сделать сетевой запрос к своим внутренним службам через вызов API от ApiGateway
с помощью GuzzleHttp
клиента. Проблема в том, что когда я делаю запрос к внутренней службе, она всегда выдает исключение Клиентское исключение.
ClientException.
Client error:
GET http://127.0.0.1:8081/v1/admin
resulted in a401 Unauthorized
response: {"error":"Unauthorized.","code":401}
Я пытался сделать сетевой запрос к тем же внутренним службам, используя почтальон; и это работает нормально. Однако по какой-то причине с GuzzleHttp
все равно не работает. Я не знаю, что я делаю неправильно. Пожалуйста, ваша помощь будет оценена по достоинству.
Вот httpClient.php в ApiGateway.
//Constructor method
public function __construct() {
$this->baseUri = config('services.auth_admin.base_uri');
}
public function httpRequest($method, $requestUrl, $formParams = [], $headers = []) {
//Instantiate the GazzleHttp Client
$client = new Client([
'base_uri' => $this->baseUri,
]);
//Send the request
$response = $client->request($method, $requestUrl, ['form_params' => $formParams, 'headers' => $headers]);
//Return a response
return $response->getBody();
}
//Internal Service Communication in ApiGateway**
public function getAdmin($header) {
return $this->httpRequest('GET', 'admin', $header);
}
ВнутреннийServiceController.php
public function getAdmin(Request $request) {
return $this->successResponse($this->authAdminService->getAdmin($request->header()));
}
I am using Lumen version: 5.8 and GuzzleHttp Version: 6.3
Вот почему я сбит с толку; заголовок запроса содержит действительный токен, когда я dd($request->header()) и внутренний клиент ожидает, что токен будет в заголовке запроса.
Можете ли вы включить этот массив заголовков, который передается в метод?
Можете ли вы изменить $client->request($method, $requestUrl, ['form_params' => $formParams, 'headers' => $headers]) на $client->request($method, $requestUrl, ['query' => $formParams, 'headers' => $headers]) при использовании метода GET?
Требуются ли для API данные в формате json? если да, вы передаете application/json как тип контента? Если да, то использование form_params
вам не поможет. Вместо этого вы должны использовать json
. Помимо этого, является ли аутентификация базовой? если да, то ваш заголовок должен быть в таком формате, $header['Authorization'] = "Basic ".base64_encode('your_api_key:your_api_secret_here');
Вы передаете свои заголовки как formParams (третий индекс вместо четвертого).
Попробуйте ниже:
return $this->httpRequest('GET', 'admin', [], $header);
Да, я точно понимаю; Я пробовал это, но все еще не работал.
Не могли бы вы обновить свой образец, чтобы мы могли видеть, что вы понимаете? - трудно помочь на основе примера кода с ошибкой
Спасибо за Ваш ответ; тогда это было очень полезно; Я только что вернулся, чтобы принять ваш ответ.
Здесь я делаю некоторые предположения, которые, надеюсь, будут вам полезны.
PHP не поддерживает пропуск необязательных параметров, поэтому при вызове httpRequest()
следует передавать пустой массив [].
public function httpRequest($method, $requestUrl, $formParams = [], $headers = [], $type='json', $verify = false) {
//Instantiate the GazzleHttp Client
$client = new Client([
'base_uri' => $this->baseUri,
]);
//the request payload to be sent
$payload = [];
if (!$verify) {
$payload['verify'] = $verify; //basically for SSL and TLS
}
//add the body to the specified payload type
$payload[$type] = $formParams;
//check if any headers have been passed and add it as well
if (count($headers) > 0) {
$payload['headers'] = $headers;
}
//Send the request
$response = $client->request($method, $requestUrl, $payload);
//Return a response
return $response->getBody();
}
Теперь вам нужно вызвать его таким образом, когда вы не передаете какие-либо form_params или body
//Internal Service Communication in ApiGateway**
public function getAdmin($header) {
return $this->httpRequest('GET', 'admin', [], $header);
}
Ошибка 401 означает, что вы не аутентифицированы, похоже, вам нужно отправить токен API с запросом.