Reindirizza a un sito esterno in un plugin?

Sto cercando di chiamare un URL esterno per effettuare l’accesso a un sito remoto dopo che gli utenti hanno effettuato l’accesso a Discourse. Tutto ciò che devo fare è reindirizzare a un URL sul sito remoto, che gestisce l’accesso lì, e poi reindirizzare nuovamente a Discourse. Quando lo faccio, il browser rifiuta il reindirizzamento a causa di 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.

Gli sviluppatori dell’app dicono che è perché sto eseguendo il reindirizzamento in modo errato (ad esempio, con una chiamata AJAX?), ma questo sembra identico a ciò che vedo nei commit menzionati qui.

Sono (ancora una volta) bloccato.

Non riesco a capire se sono semplicemente stupido o se dovrebbero inviare le intestazioni Access-Control-Allow-Origin (e in tal caso, questo non potrebbe funzionare per nessuno dei loro clienti? cosa che sembra improbabile).

Ecco il mio codice:

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: Gli sviluppatori hanno condiviso un’app Rails che utilizza redirect_to esattamente come faccio io e affermano che funziona. C’è qualcosa di specifico in Discourse che fa sì che un redirect_to si comporti diversamente perché si trova… all’interno di Ember o qualcosa del genere?

Sono certo che ci sia qualcosa di semplice che mi sfugge. La mia ultima soluzione è stata provare:

      url = thinkific_sso_url(payload)
      redirect_location = "<!DOCTYPE html><html><head><meta http-equiv=\"Refresh\" content = \"5; url='#{url}'\" /></head><body>Questo è il mio corpo</body></html>"
      Rails.logger.info "REINDIRIZZAMENTO... #{redirect_location}"

      render plain: redirect_location

Se salvo il testo contenuto in redirect_location in un file e lo apro nel browser, vengo effettuato l’accesso a Thinkific e reindirizzato a Discourse. Purtroppo, la stessa cosa non funziona quando faccio clic su “Accedi” nel browser.

Qualcuno può darmi una mano?

Mi dispiace dover tirare in ballo te, @sam, ma credo che ci sia qualcosa di specifico di Discourse e rapido con cui puoi aiutarmi, dato che ci sto lavorando da due settimane.

Ho fatto funzionare il mio codice inserendo un proxy nel mezzo, ma non mi sembra una soluzione molto buona.

Quando provo a redirect_to un sito esterno in un SessionController che sto sovrascrivendo, ricevo un errore CORS. Lo stesso codice di Thinkific non sembra avere questo problema. C’è qualcosa di speciale nel fare un redirect da dentro site_url/session? Devo eseguire il redirect da JavaScript in qualche modo? Se è così, potresti indicarmi la direzione generale su come potrebbe funzionare?

Onestamente non sono sicuro di cosa stia succedendo qui. redirect_to dovrebbe funzionare con un URL esterno.

Oh. Maledizione.

Ridireziona davvero, ma genera una violazione CORS. È bizzarro, perché una ridirezione che sembra esattamente la stessa non causa una violazione CORS nel loro codice di esempio Rails. Speravo che ci fosse qualcosa di speciale nel farlo all’interno di Ember. O qualcosa del genere.

Addio quindi alla mia speranza che si trattasse di qualcosa di stupido e ovvio.

Grazie mille. Lo apprezzo davvero.

Sono abbastanza sicuro che, poiché il modale di login è realizzato in AJAX (in base_url/session), il browser rifiuta di eseguire un redirect_to senza che l’altra parte invii le intestazioni CORS.

Credo di aver bisogno di un modo per (e non so come descriverlo) uscire dall’AJAX, in modo che per il browser sembri un reindirizzamento normale e non un reindirizzamento in AJAX.

Oppure, esiste un modo per rendere la pagina di login non basata su AJAX?

Ciao @pfaffman

Hai avuto fortuna con questa situazione? Sto riscontrando lo stesso problema utilizzando il login SSO di Discourse da un’API web ASP.NET Core.

Il browser dell’app Angular genera l’errore ‘intestazione di controllo accettazione non presente’ una volta che la richiesta viene reindirizzata dall’API all’app Angular (dopo che Discourse ha inviato correttamente la risposta).

App web Angular → API ASP.NET → L’API chiama Discourse SSO → Discourse restituisce i valori all’API del server ASP.NET → Il server API reindirizza la chiamata di ritorno all’URL dell’app Angular → Il browser genera un errore che l’URL di Discourse non è accessibile a causa dell’assenza dell’intestazione ‘Access control origin’.

image

Tutte le impostazioni CORS su Discourse sono configurate correttamente, così come sul server web dell’API ASP.NET.

Sembra simile al problema che hai affrontato in precedenza. Spero tu possa chiarire come risolverlo.