Redirecionar para um site externo em um plugin?

Estou tentando chamar uma URL externa para fazer login em um site remoto após os usuários fazerem login no Discourse. Tudo o que preciso é redirecionar para uma URL no site remoto, que realiza o login lá e, em seguida, redireciona de volta para o Discourse. Quando faço isso, o navegador recusa o redirecionamento devido ao CORS:

Acesso ao XMLHttpRequest em 'https://SITE/api/sso/v2/sso/jwt?' (redirecionado de 'https://testing.literatehosting.com/session') a partir da origem 'https://testing.literatehosting.com' foi bloqueado pela política CORS: A resposta à solicitação prévia não passou na verificação de controle de acesso: O cabeçalho 'Access-Control-Allow-Origin' não está presente no recurso solicitado.

Os desenvolvedores do aplicativo dizem que é porque estou fazendo o redirecionamento errado (por exemplo, com uma chamada AJAX?), mas isso parece o mesmo que, por exemplo, o que vejo nos commits mencionados aqui.

Estou (mais uma vez) sem ideias.

Não consigo dizer se sou apenas burro ou se eles precisam enviar cabeçalhos Access-Control-Allow-Origin (e, se for esse o caso, isso não pode estar funcionando para nenhum de seus clientes? o que parece exagerado).

Aqui está meu código:

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 # plugin is enabled and has api key and url
          sign_into_thinkific(user)
        else
          render_serialized(user, UserSerializer)
        end
      end
    end

    def sign_into_thinkific(user)
      # do stuff to generate payload

      redirect_to thinkific_sso_url(payload) # also tried 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

EDIT: Os desenvolvedores compartilharam um aplicativo Rails que usa redirect_to exatamente como eu, e eles afirmam que funciona. Há algo no Discourse que faz com que ele faça algo diferente com um redirect_to porque está… dentro do Ember, ou algo assim?

Com certeza estou perdendo algo simples aqui. Minha última tentativa foi:

      url = thinkific_sso_url(payload)
      redirect_location = "<!DOCTYPE html><html><head><meta http-equiv=\"Refresh\" content = \"5; url='#{url}'\" /></head><body>Este é meu corpo</body></html>"
      Rails.logger.info "REDIRECIONANDO... #{redirect_location}"

      render plain: redirect_location

Se eu salvar o texto que está em redirect_location em um arquivo e abri-lo no meu navegador, consigo fazer login no Thinkific e sou redirecionado para o Discourse. Infelizmente, o mesmo não funciona quando clico em login no meu navegador.

Alguém pode me dar uma força?

Peço desculpas por te chamar, @sam, mas sinto que há algo específico do Discourse e rápido com o que você pode me ajudar, e tenho trabalhado nisso há duas semanas.

Fiz meu código funcionar inserindo um proxy no meio, mas isso não parece ser uma solução muito boa.

Quando tento redirect_to um site externo no SessionController que estou sobrescrevendo, recebo um erro de CORS. O mesmo código do Thinkific parece não ter esse problema. Há algo especial em fazer um redirecionamento dentro de site_url/session? Preciso fazer o redirecionamento via JavaScript de alguma forma? Se sim, você poderia me indicar a direção geral de como isso poderia funcionar?

Sinceramente, não tenho certeza do que está acontecendo aqui. redirect_to deveria funcionar para uma URL externa.

Oh. Droga.

Ele realmente redireciona, mas gera uma violação de CORS. É bizarro, pois o que parece ser exatamente o mesmo redirecionamento não causa violação de CORS no código de exemplo Rails deles. Eu esperava que houvesse algo especial em fazer isso dentro do Ember. Ou algo assim.

Então, esqueça minha esperança de que fosse algo bobo e óbvio.

Muito obrigado. Agradeço muito.

Tenho quase certeza de que, como o modal de login é feito via AJAX (em base_url/session), o navegador se recusa a realizar um redirect_to sem que o outro lado envie os cabeçalhos CORS.

O que eu acho que preciso é de alguma forma (e não faço ideia de como descrever isso) sair do contexto do AJAX, de modo que, para o navegador, pareça um redirecionamento normal, e não um redirecionamento dentro do AJAX.

Ou, existe alguma maneira de fazer com que o login seja uma página não AJAX?

Oi @pfaffman

Conseguiu resolver essa situação? Estou enfrentando o mesmo problema ao usar o login SSO do Discourse a partir de uma API web ASP.NET Core.

O navegador do aplicativo Angular está lançando o erro “cabeçalho de controle de aceitação não presente” assim que a solicitação é redirecionada da API para o aplicativo Angular (após o Discourse enviar a resposta com sucesso).

Aplicativo web Angular → API ASP.NET → Chamadas da API ao SSO do Discourse → Discourse retorna os valores para a API do servidor ASP.NET → O servidor da API redireciona a chamada de volta para a URL do aplicativo Angular → O navegador lança erro de que a URL do Discourse não é acessível devido à ausência do “cabeçalho de origem de controle de acesso”.

image

Todas as configurações de CORS no Discourse estão corretas, assim como no servidor web da API ASP.NET.

Parece semelhante ao problema que você enfrentou anteriormente. Espero que você possa nos dar uma luz sobre como resolver isso.