Перенаправление на внешний сайт в плагине?

Я пытаюсь вызвать внешний URL для входа на удаленный сайт после того, как пользователи вошли в Discourse. Всё, что мне нужно сделать, — это перенаправить на URL на удаленном сайте, который выполнит вход там, а затем перенаправит обратно в Discourse. Когда я делаю это, браузер отказывается выполнять перенаправление из-за CORS:

Access to XMLHttpRequest at 'https://SITE/api/sso/v2/sso/jwt?' (redirected from 'https://testing.literatehosting.com/session') from origin 'https://testing.literatehosting.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Разработчики приложения говорят, что проблема в том, что я делаю перенаправление неправильно (например, через ajax-запрос?), но это выглядит так же, как, например, то, что я вижу в коммитах, упомянутых здесь.

Я снова (как всегда) в тупике.

Не могу понять, просто ли я глуп, или им действительно нужно отправлять заголовки Access-Control-Allow-Origin (и если это так, то это не должно работать ни для одного из их клиентов? что кажется маловероятным).

Вот мой код:

after_initialize do
  class ::SessionController
    def login(user)
      puts "\n\n\n\LOGIN happening!\n\n\n\n"
      session.delete(ACTIVATE_USER_KEY)
      log_on_user(user)

      if payload = cookies.delete(:sso_payload)
        sso_provider(payload)
      else
        if true # плагин включен и имеет api-ключ и url
          sign_into_thinkific(user)
        else
          render_serialized(user, UserSerializer)
        end
      end
    end

    def sign_into_thinkific(user)
      # выполнить действия для генерации payload

      redirect_to thinkific_sso_url(payload) # также пробовал redirect_to 
 generate_url(thinkific_sso_url(payload))

    end

    def generate_url(url, params = {})
      puts "\n\n\nGenerate URL: #{url}\n\n\n"
      uri = URI(url)
      uri.query = params.to_query
      uri.to_s
    end

    def thinkific_sso_url(payload)
      current_url="https://#{GlobalSetting.hostname}/"
      url = "https://#{SiteSetting.thinkific_site_url}/api/sso/v2/sso/jwt?jwt=#{payload}"
      url += "&return_to=#{URI.escape(current_url)}" 

      url
    end

  end
end

РЕДАКТИРОВАНИЕ: Разработчики поделились Rails-приложением, которое использует redirect_to точно так же, как и я, и утверждают, что это работает. Есть ли что-то особенное в Discourse, из-за чего redirect_to ведёт себя иначе, потому что он находится… внутри Ember или что-то в этом роде?

Конечно, я что-то упускаю. Моя последняя попытка выглядит так:

      url = thinkific_sso_url(payload)
      redirect_location = "<!DOCTYPE html><html><head><meta http-equiv=\"Refresh\" content = \"5; url='#{url}'\" /></head><body>Это мой текст</body></html>"
      Rails.logger.info "ПЕРЕНАПРАВЛЕНИЕ... #{redirect_location}"

      render plain: redirect_location

Если я сохраню содержимое переменной redirect_location в файл и открою его в браузере, я успешно войду в Thinkific и буду перенаправлен на Discourse. К сожалению, при нажатии кнопки «Войти» в браузере ничего не происходит.

Может, кто-нибудь подскажет, в чём дело?

Мне жаль, что я вынужден тебя подгонять, @sam, но мне кажется, что у тебя есть какое-то быстрое и специфичное для Discourse решение, с которым ты можешь мне помочь, а я уже работаю над этим две недели.

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

Когда я пытаюсь выполнить redirect_to на внешний сайт в SessionController, который я переопределяю, возникает ошибка CORS. Тот же код из Thinkific, похоже, не имеет этой проблемы. Есть ли что-то особенное в перенаправлении изнутри site_url/session? Нужно ли мне выполнять перенаправление через JavaScript? Если да, не мог бы ты указать мне общее направление, как это может работать?

Честно говоря, я не уверен, что здесь происходит. redirect_to должен работать с внешними URL-адресами.

Ох. Чёрт.

Оно действительно перенаправляет, но возникает нарушение CORS. Это странно, потому что точно такое же перенаправление не вызывает нарушения CORS в их образцовом коде на Rails. Я надеялся, что в чём-то особенном при выполнении этого внутри Ember. Или что-то в этом роде.

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

Большое спасибо. Я очень это ценю.

Я довольно уверен, что поскольку модальное окно входа реализовано через AJAX (в base_url/session), браузер отказывается выполнять redirect_to, если другая сторона не отправляет заголовки CORS.

Мне, кажется, нужно каким-то образом (и я не знаю, как это описать) выйти из режима AJAX, чтобы для браузера это выглядело как обычное перенаправление, а не перенаправление внутри AJAX.

Или, может быть, есть способ сделать страницу входа не-асинхронной?

Привет, @pfaffman

Есть ли какие-то успехи в решении этой ситуации? У меня возникла та же проблема при использовании входа через SSO Discourse из веб-API на ASP.NET Core.

Браузер Angular-приложения выдаёт ошибку «заголовок accept control отсутствует» после того, как запрос перенаправляется с API на Angular-приложение (после того как Discourse успешно вернул ответ).

Цепочка вызовов:
Angular-веб-приложение → ASP.NET API → вызов SSO Discourse → Discourse возвращает значения на сервер API ASP.NET → сервер API перенаправляет обратный вызов на URL Angular-приложения → браузер выдаёт ошибку, что URL Discourse недоступен из-за отсутствия заголовка «Access-Control-Origin».

image

Все настройки CORS на стороне Discourse и на веб-сервере API ASP.NET настроены правильно.

Это звучит похоже на проблему, с которой вы сталкивались ранее. Надеюсь, вы сможете пролить свет на то, как её решить.