Ryan_NR
(Ryan)
22.Июнь.2020 15:26:10
1
Привет!
Я пытаюсь выполнить вызов API для создания новой темы. Discourse API Docs
Используя Postman, я отправляю API-ключ, имя пользователя и Content-Type в заголовках, а JSON-данные — в теле запроса.
Я проверил, что API-имя пользователя и ключ верны, но вызов API возвращает HTML-страницу входа в систему.
Это ожидаемое поведение? Как можно обойти эту проблему?
Falco
(Falco)
22.Июнь.2020 16:35:15
2
Не могли бы вы вставить версию API-вызова на cURL, которую вы пытаетесь выполнить?
Ryan_NR
(Ryan)
23.Июнь.2020 07:05:53
3
Конечно…
curl -X POST 'https://staging-discuss.newrelic.com/posts.json' \
-H 'Api-Username: RyanVeitch' -i \
-H 'Api-Key: My-API-Key' -i \
-H 'Content-Type: application/json' \
-d \
'{
"title": "Мой замысловатый заголовок",
"raw": "Какой-то случайный текст для заполнения моей темы",
"category": 212,
"created_at": "2020-06-22"
}'
В терминале я получаю следующий вывод:
HTTP/1.1 307 Временное перенаправление
Proxied-By: Service Gateway
Strict-Transport-Security: max-age=31536000; includeSubDomains
Location: https://staging-login.newrelic.com/login?return_to=https%3A%2F%2Fstaging-discuss.newrelic.com%2Fposts.json
content-type: text/plain;charset=UTF-8
content-length: 138
Перенаправление на другой URI: https://staging-login.newrelic.com/login?return_to=https%3A%2F%2Fstaging-discuss.newrelic.com%2Fposts.json%
Ryan_NR
(Ryan)
23.Июнь.2020 15:36:48
4
Дайте знать, если с моей стороны потребуется что-то ещё для помощи в устранении неполадок
Falco
(Falco)
23.Июнь.2020 17:16:16
5
Похоже, у вас очень нестандартная конфигурация с прокси-сервером посередине.
Это не является стандартным поведением Discourse, поэтому, судя по всему, причина кроется в вашем специальном прокси-решении.
Возможно, есть какой-то специальный заголовок, который можно отправить, чтобы обойти прокси? Нужно проверить документацию по этому продукту.
Ryan_NR
(Ryan)
24.Июнь.2020 06:45:09
6
Круто! Спасибо @Falco — я подключу нашу команду разработчиков
Ryan_NR
(Ryan)
25.Июнь.2020 09:31:40
7
Привет, @Falco ! Мне удалось пройти через прокси, но теперь я получаю ошибки 403 BAD CSRF.
Кажется, эта тема осталась незавершённой…
Can you share with me your actual ruby code to make this request? I’m unable to reproduce this locally. Here is the Postman json call I’m making and I’m always getting a response back:
[image]
[image]
Also I don’t think you need the extra post["raw"] parameter.
Parameters: {"title"=>"RT @love_se4: One of those hidden gems in the local community, you just have to try. Over 170 different gins. Proper mixologists who know h…", "raw"=>"https://twitter.com/se23_tweets/status/1127663613412630529"…
Есть ли у тебя какие-то идеи, как обойти эти ошибки?
blake
(Blake Erickson)
25.Июнь.2020 15:37:19
8
Я только что протестировал ваш пример команды curl локально, и у меня всё работает отлично, значит синтаксис верный. Возможно, прокси удаляет некоторые заголовки? Это могло бы стать причиной ошибок BAD CSRF, так как в таком случае он больше не может читать/получать доступ к учётным данным API.
Ryan_NR
(Ryan)
25.Июнь.2020 15:51:39
9
Спасибо, @blake
Наш прокси — это полностью кастомное решение собственной разработки, которое служит фронтенд-слоем для публичного доступа.
Я подключен через VPN к нашей внутренней сети и обращаюсь не к публичному URL, а к бэкенд-URL (находящемуся за прокси), поэтому запросы не должны проходить через прокси.
Наша тестовая версия Discourse — 2.3.10.
Ведёт ли API себя иначе в этой версии?
blake
(Blake Erickson)
25.Июнь.2020 16:09:10
10
Нет, в версии v2.3.10 по-прежнему присутствует вся аутентификация на основе заголовков, поэтому поведение не должно измениться.
Вы попадаете на эту строку:
protect_from_forgery
# Default Rails 3.2 lets the request through with a blank session
# we are being more pedantic here and nulling session / current_user
# and then raising a CSRF exception
def handle_unverified_request
# NOTE: API key is secret, having it invalidates the need for a CSRF token
unless is_api? || is_user_api?
super
clear_current_user
render plain: "[\"BAD CSRF\"]", status: 403
end
end
before_action :check_readonly_mode
before_action :handle_theme
before_action :set_current_user_for_logs
before_action :clear_notifications
before_action :set_locale
before_action :set_mobile_view
before_action :block_if_readonly_mode
что означает, что ваш запрос составлен некорректно каким-то образом, и система не может определить, что это API-запрос.
blake
(Blake Erickson)
25.Июнь.2020 16:25:46
11
Поскольку это тестовый экземпляр, а не локальная среда, перед обращением к Discourse должен работать nginx или другой веб-сервер. Возможно, nginx удаляет некоторые заголовки в зависимости от вашей конфигурации. Эта информация может отображаться в логах nginx.
Это строка, где credentials API считываются из заголовков запроса. Вы также можете добавить отладочные инструкции в этот файл, чтобы проверить, доходят ли заголовки до этого места.
if uid
user = User.find_by(id: uid.to_i)
end
@env[CURRENT_USER_KEY] = user
return user
end
request = @request
user_api_key = @env[USER_API_KEY]
api_key = @env.blank? ? nil : @env[HEADER_API_KEY] || request[API_KEY]
auth_token = request.cookies[TOKEN_COOKIE] unless user_api_key || api_key
current_user = nil
if auth_token && auth_token.length == 32
limiter = RateLimiter.new(nil, "cookie_auth_#{request.ip}", COOKIE_ATTEMPTS_PER_MIN , 60)
if limiter.can_perform?
@user_token = UserAuthToken.lookup(auth_token,
Ryan_NR
(Ryan)
25.Июнь.2020 17:07:27
12
@blake
Спасибо! Я обсудю это с нашей командой разработчиков
Очень ценю вашу помощь