Rediriger vers un site externe dans un plugin ?

J’essaie d’appeler une URL externe pour me connecter à un site distant après que les utilisateurs se sont connectés à Discourse. Tout ce que j’ai à faire est de rediriger vers une URL sur le site distant, qui effectue la connexion là-bas, puis de rediriger vers Discourse. Quand je le fais, le navigateur refuse la redirection à cause de CORS :

Accès à XMLHttpRequest à 'https://SITE/api/sso/v2/sso/jwt?' (redirigé depuis 'https://testing.literatehosting.com/session') depuis l'origine 'https://testing.literatehosting.com' a été bloqué par la politique CORS : La réponse à la requête préliminaire ne passe pas le contrôle d'accès : L'en-tête 'Access-Control-Allow-Origin' est absent de la ressource demandée.

Les développeurs de l’application disent que c’est parce que je fais la redirection incorrectement (par exemple, avec un appel Ajax ?), mais cela ressemble à ce que je vois, par exemple, dans les commits mentionnés ici.

Je suis (encore une fois) perdu.

Je ne sais pas si je suis simplement stupide ou s’ils doivent envoyer les en-têtes Access-Control-Allow-Origin (et si c’est le cas, alors cela ne peut pas fonctionner pour l’un de leurs clients ? ce qui semble exagéré).

Voici mon code :

after_initialize do
  class ::SessionController
    def login(user)
      puts "\n\n\n\CONNEXION en cours !\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 # le plugin est activé et possède une clé API et une URL
          sign_into_thinkific(user)
        else
          render_serialized(user, UserSerializer)
        end
      end
    end

    def sign_into_thinkific(user)
      # faire des choses pour générer le payload

      redirect_to thinkific_sso_url(payload) # j'ai aussi essayé redirect_to 
 generate_url(thinkific_sso_url(payload))

    end

    def generate_url(url, params = {})
      puts "\n\n\nGénérer l'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

MODIFICATION : Les développeurs ont partagé une application Rails qui utilise redirect_to exactement comme moi, et ils affirment que cela fonctionne. Y a-t-il quelque chose dans Discourse qui fait qu’il traite différemment un redirect_to parce que c’est… dans Ember, ou autre chose ?

Il doit bien y avoir quelque chose de simple que j’oublie ici. Ma dernière tentative consiste à exécuter :

      url = thinkific_sso_url(payload)
      redirect_location = "<!DOCTYPE html><html><head><meta http-equiv=\"Refresh\" content = \"5; url='#{url}'\" /></head><body>Ceci est mon corps</body></html>"
      Rails.logger.info "REDIRECTION EN COURS... #{redirect_location}"

      render plain: redirect_location

Si j’enregistre le texte de redirect_location dans un fichier et que je l’ouvre dans mon navigateur, je suis connecté à Thinkific et redirigé vers Discourse. Malheureusement, cela ne fonctionne pas lorsque je clique sur « Se connecter » dans mon navigateur.

Quelqu’un peut-il me donner un coup de main ?

Désolé de te mettre sur la sellette, @sam, mais j’ai l’impression qu’il y a quelque chose de spécifique à Discourse et rapide sur lequel tu pourrais m’aider, alors que je travaille là-dessus depuis deux semaines.

J’ai fait fonctionner mon code en insérant un proxy au milieu, mais cela ne semble pas être une très bonne solution.

Lorsque j’essaie de redirect_to un site externe dans le SessionController que je surcharge, j’obtiens une erreur CORS. Le même code provenant de Thinkific ne semble pas avoir ce problème. Y a-t-il quelque chose de spécial à faire une redirection depuis site_url/session ? Dois-je effectuer la redirection via JavaScript d’une manière ou d’une autre ? Si oui, pourrais-tu m’orienter dans la bonne direction pour savoir comment cela pourrait fonctionner ?

Honnêtement, je ne suis pas sûr de ce qui se passe ici. redirect_to devrait fonctionner vers une URL externe.

Oh. Zut alors.

Cela redirige effectivement, mais cela génère une violation CORS. C’est bizarre, car ce qui semble être exactement la même redirection ne provoque pas de violation CORS dans leur code d’exemple Rails. J’espérais qu’il y avait quelque chose de spécial à le faire dans Ember. Ou autre chose.

Adieu donc mon espoir qu’il s’agisse d’une bêtise évidente.

Merci beaucoup. Je vous en suis vraiment reconnaissant.

Je suis assez certain que, comme la fenêtre modale de connexion est gérée en AJAX (dans base_url/session), le navigateur refuse d’effectuer un redirect_to sans que l’autre partie n’envoie des en-têtes CORS.

Je pense avoir besoin d’un moyen (et je ne sais pas du tout comment le décrire) de sortir du contexte AJAX afin que, pour le navigateur, cela ressemble à une redirection normale et non à une redirection dans AJAX.

Ou bien, existe-t-il un moyen de rendre la page de connexion non-AJAX ?

Bonjour @pfaffman,

Avez-vous eu des nouvelles concernant cette situation ? Je rencontre le même problème lors de l’utilisation de la connexion SSO Discourse depuis une API web ASP.NET Core.

Le navigateur de l’application Angular signale l’erreur « en-tête de contrôle d’acceptation manquant » une fois la requête redirigée de l’API vers l’application Angular (après que Discourse a renvoyé une réponse avec succès).

Application web Angular → API ASP.NET → Appel API vers SSO Discourse → Discourse renvoie les valeurs à l’API du serveur ASP.NET → Le serveur API redirige l’appel vers l’URL de l’application Angular → Le navigateur signale une erreur indiquant que l’URL Discourse n’est pas accessible en raison de l’absence de l’en-tête « Access-Control-Origin ».

image

Tous les paramètres CORS sont correctement configurés sur Discourse et sur le serveur web de l’API ASP.NET.

Cela ressemble au problème que vous avez rencontré précédemment. J’espère que vous pourrez m’éclairer sur la manière de résoudre ce problème.