web-dev-qa-db-fra.com

Passer des paramètres via OmniAuth

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.

53
synapse

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.

76
nfriend21

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

22
user566245

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 )

12
Nimo

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

7
jefflunt

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

6
David Morales

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é.

1
jefflunt