J'ai besoin de passer quelques paramètres à l'action de rappel. À en juger par le code source, OmniAuth devrait ajouter une chaîne de requête à l'URL de rappel, mais ce n'est étrangement pas le cas. Quand j'ouvre
/auth/facebook?from=partner
... et redirigez-vous vers Facebook, return_url
est juste
/auth/facebook/callback
... sans aucun paramètre.
Après avoir lutté avec toutes les réponses ci-dessus, j'ai compris quoi faire concernant Facebook, qui par défaut n'affiche pas les paramètres dans request.env["omniauth.auth"]
.
Donc - Si vous utilisez une chaîne de requête pour le rappel, similaire à quelque chose comme ceci:
"/auth/facebook?website_id=#{@website.id}"
La seule façon d'obtenir ce paramètre website_id est d'utiliser request.env["omniauth.params"]
. REMARQUE: ASSUREZ-VOUS D'UTILISER omniauth.params et non omniauth.auth - celui-ci m'a fait trébucher pendant un certain temps.
Ensuite, pour tester cela, vous pouvez l'inspecter dans l'action de votre contrôleur (notez la ligne RAISE ...):
def create
raise request.env["omniauth.params"].to_yaml
# the rest of your create action code...
end
Vous devriez y voir votre paramètre. Génial. Maintenant, revenez à votre contrôleur et supprimez cette ligne RAISE. Ensuite, vous pouvez accéder au paramètre comme suit dans l'action de votre contrôleur:
params = request.env["omniauth.params"]
website_id = params["website_id"]
REMARQUE: dans les paramètres ["website_id"], vous devez utiliser des guillemets et NON un symbole.
Je suppose que le cookie fonctionne mais pourquoi faire tout cela quand vous pouvez utiliser la variable d'état comme documenté ici: https://github.com/mkdynamic/omniauth-facebook
Voici comment je l'ai utilisé:
lors de la création de l'URL, vous pouvez simplement ajouter un état dans la chaîne de requête et il sera également disponible dans l'URL de rappel.
user_omniauth_authorize_path(:facebook, :display => 'page', :state=>'123') %>
maintenant l'URL de rappel sera
http://localhost:3000/users/auth/facebook/callback?state=123&code=ReallyLongCode#_=_
Maintenant, dans le gestionnaire de rappel, vous pouvez traiter l'état
Vous pouvez utiliser le :params
options, comme dans
omniauth_authorize_path(:user, :facebook, var: 'value', var2: 'value2' )
et plus tard dans le rappel, vous pouvez accéder à request.env['omniauth.params']
pour obtenir le hachage! :)
(copié de cette réponse )
Ce que vous voulez faire est de définir dynamiquement votre rappel pour inclure le nom du partenaire dans l'url ( pas les paramètres url), sur un par transaction d'authentification , en fonction du partenaire impliqué. Cela signifie définir l'URL de rappel de manière dynamique, pour chaque demande d'authentification. Voir ce billet de blog pour commencer . L'URL de rappel supprime automatiquement les paramètres d'URL, comme vous l'avez remarqué, donc cela ne fonctionnera pas avec les paramètres.
Donc, si au lieu d'essayer de passer le nom/id du partenaire en tant que paramètre (qui est supprimé), vous avez structuré vos itinéraires de sorte que le partner_id
et OmniAuth provider
faisaient partie de l'URL de rappel, alors vous auriez quelque chose comme:
/auth/:omniauth_provider/callback/:partner_id
... où un rappel valide serait quelque chose comme
/auth/facebook/callback/123456
... alors vous saurez qu'un rappel donné est venu de Facebook, avec l'identifiant du partenaire 123456
OmniAuth a déjà un moyen intégré de savoir où était l'utilisateur, il s'appelle "Origin" comme documenté ici:
https://github.com/intridea/omniauth/wiki/Saving-User-Location
Vous savez, je pense que je vais peut-être essayer de résoudre ce problème à la dure.
Les cookies pourraient être la réponse. Je pense que vous pouvez résoudre ce problème en demandant à votre action de connexion de stocker un cookie, puis de le rediriger vers le bon /auth/:provider
chemin d'accès pour l'authentification et lorsque le rappel est déclenché (dans SessionsController#create
), vous venez de lire le cookie pour savoir où les rediriger.
Donc, en ce moment, votre lien "se connecter avec Facebook" (ou tout ce que vous avez dans votre application) va probablement à /auth/facebook
. Au lieu de cela, si vous avez créé une action personnalisée comme
POST /partner_auth
... et l'a appelé avec l'url ...
POST example.com/partner_auth?from=partner&provider=facebook
Ensuite, vous pourriez avoir un contrôleur comme:
class PartnerAuth < ApplicationController
def create
cookies[:from] = params[:from] # creates a cookie storing the "from" value
redirect_to "auth/#{params[:provider]"
end
end
Puis dans le SessionsController#create
action, vous auriez ...
def create
...
destination = cookies[:from]
cookies[:from].delete
redirect_to destination # or whatever the appropriate thing is for your
# app to do with the "from" information
end
J'ai essayé de créer une application de démonstration pour accomplir ce que j'avais décrit dans l'autre réponse, mais vous avez raison - c'était trop compliqué d'essayer d'injecter dynamiquement un rappel personnalisé dans le code OmniAuth. Il existe une option de configuration pour remplacer le rappel par défaut, mais il ne semble pas facile de le définir dynamiquement.
Donc, il m'est apparu que les cookies seraient beaucoup plus simples, spécifiques à l'utilisateur, et puisque vous n'avez théoriquement besoin de stocker ces informations from
que très peu de temps (entre le moment où l'utilisateur tente de s'authentifier et le moment où le le rappel est déclenché), ce n'est pas grave de créer un cookie, puis de le supprimer lorsque le rappel est touché.