Запрос HTTP Ruby GET NET не работает с AUTHORIZATION и ACCEPT при передаче в заголовке - PullRequest
1 голос
/ 12 июня 2019

Я использовал приведенный ниже код для вызова стороннего API. Этот код работает нормально (я изменил URL и учетные данные, но структура кода такая же):

require 'base64'
require 'httparty'
require 'json'

######################################################################
# Get the token first
######################################################################
consumer_key    = "my_key"
consumer_secret = "my_secret"

credentials = Base64.encode64("#{consumer_key}:#{consumer_secret}").gsub("\n", '')
url = "https://mysite/token"
body = "grant_type=client_credentials"

headers = {
  "Authorization" => "Basic #{credentials}",
  "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
}

r = HTTParty.post(url, body: body, headers: headers)
bearer_token = JSON.parse(r.body)['access_token']

######################################################################
# Use the token in a call as authorisation header
######################################################################
api_url = "https://apisite/the_value_i_am_looking_for_in_the_api"

url = URI.parse(api_url)
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = true

# If we are just passing a key that doesn't need to be in the token format
headers = {
  'Authorization' => "Bearer #{bearer_token}"
}

# Get the response back (he data is in the response body: resp.body )
resp = req.get(url, headers)

Моя проблема заключается в том, что провайдеры API изменили свой API, поэтому теперь вам нужно передать "accept" в вызов через заголовок. Я использовал POSTMAN, чтобы сделать вызов, добавил согласие в заголовок и смог заставить его работать без проблем. Все идет нормально.

Затем я изменил свой код ruby, чтобы расширить раздел заголовков, включив в него команду accept, используя следующий код:

headers = {
  'Authorization' => "Bearer #{bearer_token}",
  'Accept' => 'application/vnd.bluebadge-api.v1+json'
}

Раньше я не добавлял заголовок accept в заголовок, поэтому, возможно, неправильно понял синтаксис.

Однако при этом возвращается неавторизованный код ответа 401:

#<Net::HTTPUnauthorized 401 Unauthorized readbody=true>

Я подумал, что у меня могут быть неверные учетные данные, поэтому удалите подтверждение, попробуйте еще раз, и это изменит код ответа 406:

#<Net::HTTPNotAcceptable 406 Not Acceptable readbody=true>

Если я изучу ответ, то получу сообщение, я ожидаю, что заголовок accept не является поддерживаемой версией. Итак, я знаю, что учетные данные верны (и тот факт, что они совпадают с учетными данными почтальона, который работает):

"{\"apiVersion\": \"1\",\"context\": null,\"id\": null,\"method\": null,\"error\": {\"code\": null,\"message\": null,\"reason\": \"Accept header version is not a currently supported version.\",\"errors\": null}}\n"

Так что я знаю, что все мои учетные данные верны, потому что я скопировал их в запрос почтальона, который работает без ошибок. Значение для заголовка принятия является правильным, потому что я скопировал это из рабочего запроса почтальона тоже.

Я в недоумении, почему это не сработает.

Я просмотрел библиотеку NET HTTP и не могу найти ничего, что могло бы мне там помочь. Я видел пару постов в других местах, которые я пробовал, и они тоже не сработали.

Я ценю любую помощь в попытке решить эту проблему.

1 Ответ

0 голосов
/ 12 июня 2019

Нашел проблему. Я использовал учетные данные из производственной среды, чтобы получить токен, а затем пытался запросить API тестовой среды. В мою защиту они выглядят очень похоже (всего 3 разных персонажа). Я думаю, что у меня был случай слепоты кода.

Код, который я разместил, работает, когда я поставил правильный URL-адрес для окружения.

Я также обнаружил, что могу использовать это:

uri = URI.parse("https://myapi/some_text")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
request["Authorization"] = "Bearer #{bearer_token}"
request["Accept"] = "application/vnd.bluebadge-api.v1+json"
response = http.request(request)

Или используя HTTParty так:

response = HTTParty.get('https://myapi/some_text', {
  headers: {"Authorization" => "Bearer #{bearer_token}", "Accept" => "application/vnd.bluebadge-api.v1+json" }
})

Я бы предпочел формат моего оригинального кода или кода HTTparty, потому что по коду легко увидеть, что вы передаете заголовки. Надеемся, что это поможет другим дважды проверить свои полномочия авторизации ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...