Я хочу запросить токен через cURL, используя Swift Alamofire. Однако до сих пор я не мог понять, как передать правильные параметры в правильном порядке, чтобы это заработало.
Описание, данное Амадеем, следующее:
let headers = [
"Content-Type": "application/x-www-form-urlencoded"
]
let params = [
"grant_type": "client_credentials"
]
Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token", method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).authenticate(user: "API", password: "API").responseJSON { response in debugPrint(response)
let result = response.result.value
print(result)
}
Ожидаемый результат — получить взамен файл JSON, включая токен для выполнения запросов API. Любая помощь высоко ценится. Спасибо
Кодировка encoding: JSONEncoding.default
не JSON, поэтому используйте encoding: URLEncoding(destination: .httpBody)
В документации сказано, что параметры должны включать grant_type:client_credentials&client_id = {client_id}&client_secret = {client_secret}
. В ваших параметрах отсутствуют идентификатор клиента и секрет клиента. Обязательно включите их, выполнив что-то вроде этого:
let params = [
"grant_type": "client_credentials&client_id=CLIENTIDHERE&client_secret=CLIENTSECRETHERE"
]
Спасибо. К сожалению, сервер Amadeus отвечает ошибкой = "invalid_request"; "error_description" = "В теле сообщения разрешены только параметры client_id, client_secret и grant_type"; title = "Недопустимые параметры";
Строка, которая должна быть передана как тело:
let params = [
"grant_type=client_credentials&client_id=CLIENTIDHERE&client_secret=CLIENTSECRETHERE"
]
Я мало знаю о Swift, но я думаю, вы могли бы сделать:
let params = [
"grant_type": "client_credentials"
"client_id" : "Your API Key"
"client_secret" : "Your API Secret"
]
Давайте воспользуемся полезными инструментами отладки Alamofire, поскольку у вас есть образец cURL
.
Давайте сломаем ваш текущий код:
let headers = ["Content-Type": "application/x-www-form-urlencoded"]
let params = ["grant_type": "client_credentials"]
let request = Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token",
method: .post,
parameters: params,
encoding: JSONEncoding.default,
headers: headers).authenticate(user: "API", password: "API")
print(request.debugDescription)
request.responseJSON { response in
debugPrint(response)
let result = response.result.value
print(result)
}
Выход:
$>curl -v \
-X POST \
-u API:API \
-H "Accept-Language: fr-US;q=1.0, en;q=0.9, fr-FR;q=0.8" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
-H "User-Agent: iOSTest/1.0 (nt.iOSTest; build:1; iOS 12.2.0) Alamofire/4.8.1" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "{\"grant_type\":\"client_credentials\"}" \
"https://test.api.amadeus.com/v1/security/oauth2/token"
Давайте по частям: Мы должны забыть о заголовках Accept-Encoding, User-Agent и Accept-Language. Я пропущу их позже.
Мы видим, что -d
(данные в httpBody) неверны.
Давайте изменим это: encoding: JSONEncoding.default
на encoding: URLEncoding(destination: .httpBody)
. Кроме того, это имеет смысл, поскольку в типе контента мы сказали, что он закодирован в URL.
Получаем тогда:
$>-d "grant_type=client_credentials"
Кажется лучше.
Мы видим -u API:API \
, которые соответствуют .authenticate(user: "API", password: "API")
. Мы можем захотеть удалить его, если сервер не управляет такой аутентификацией, и вместо этого поместить его в параметры.
Итак, теперь давайте изменим параметры:
let params = ["grant_type": "client_credentials",
"client_id" : "APIKey",
"client_secret" : "APISecret"]
Мы получили:
$>-d "client_id=APIKey&client_secret=APISecret&grant_type=client_credentials" \
Тогда это должно сработать.
Порядок не тот, но серверу на это наплевать. Это должен быть ключ/доступ, а не индекс/доступ.
Итак, окончательно:
let headers = ["Content-Type": "application/x-www-form-urlencoded"]
let params = ["grant_type": "client_credentials",
"client_id" : "APIKey",
"client_secret" : "APISecret"]
let request = Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token",
method: .post,
parameters: params,
encoding: URLEncoding(destination: .httpBody),
headers: headers)
print(request.debugDescription)
request.responseJSON { response in
debugPrint(response)
let result = response.result.value
print(result)
}
Вывод (с пропущенными заголовками):
$ curl -v \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=APIKey&client_secret=APISecret&grant_type=client_credentials" \
"https://test.api.amadeus.com/v1/security/oauth2/token"
прежде всего: Ваше решение оказалось именно тем, что я искал. Спасибо за это. Я отредактировал ваш ответ и добавил вызов API. К сожалению, он возвращает неизвестно. Любые предложения, почему это может быть так?
Токен безопасности BTW хранит значение из метода .post
Не пытайтесь отредактировать мои ответы другим вопросом. Вместо этого создайте новый вопрос.
Извиняюсь. Создал новый вопрос
Отметьте это (stackoverflow.com/questions/53637437/alamofire-with-d/…), так как у вас есть
cURL
. Кроме того, работает ли это, если вы поместите завиток в терминал?