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?
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.
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?
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.
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?
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’.
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.