Ruby-on-rails 通过 OmniAuth 传递参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9890985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 03:07:31  来源:igfitidea点击:

Passing parameters through OmniAuth

ruby-on-railsomniauth

提问by synapse

I need to pass some parameters to callback action. Judging from the source code, OmniAuth should add query string to callback URL but strangely it does not. When I open

我需要将一些参数传递给回调动作。从源代码来看,OmniAuth 应该将查询字符串添加到回调 URL 中,但奇怪的是它没有。当我打开

/auth/facebook?from=partner

...and get redirected to Facebook, return_urlis just

...并被重定向到 Facebook,return_url只是

/auth/facebook/callback

...without any parameters.

...没有任何参数。

回答by nfriend21

After struggling with all the above answers, I figured out what to do regarding Facebook, which by default does not display the params in request.env["omniauth.auth"].

在努力解决上述所有答案之后,我想出了如何处理Facebook,默认情况下它不会在request.env["omniauth.auth"].

So -- If you are using a query string for the callback, similar to something like this:

所以——如果你在回调中使用查询字符串,类似于这样的:

"/auth/facebook?website_id=#{@website.id}"

The only way to get that website_id param is by using request.env["omniauth.params"]. NOTE: MAKE SURE YOU USE omniauth.params and not omniauth.auth -- this one tripped me up for a while.

获取该 website_id 参数的唯一方法是使用request.env["omniauth.params"]. 注意:请确保您使用 omniauth.params 而不是 omniauth.auth - 这个让我绊倒了一段时间

Then, to test this out, you can inspect it within your controller action (notice the RAISE line...):

然后,为了测试这一点,您可以在控制器操作中检查它(注意 RAISE 行...):

def create
  raise request.env["omniauth.params"].to_yaml 
  # the rest of your create action code...
end

You should see your parameter there. Great. Now, go back to your controller and remove that RAISE line. Then, you can access the param as follows in your controller action:

你应该在那里看到你的参数。伟大的。现在,返回到您的控制器并删除该 RAISE 线。然后,您可以在控制器操作中按如下方式访问参数:

params = request.env["omniauth.params"]
website_id = params["website_id"]

NOTE: in params["website_id"] you need to use quotes and NOT a symbol.

注意:在 params["website_id"] 中,您需要使用引号而不是符号。

回答by user566245

I guess the cookie thing works but why do all that when you can use the state variable as documented here: https://github.com/mkdynamic/omniauth-facebook

我想 cookie 的事情有效,但是当您可以使用此处记录的状态变量时为什么要这样做:https: //github.com/mkdynamic/omniauth-facebook

This is how I used it:

这是我使用它的方式:

when creating the url you can just add state in the Query String and it will be available in the callback url as well.

创建 url 时,您只需在查询字符串中添加状态,它也将在回调 url 中可用。

user_omniauth_authorize_path(:facebook, :display => 'page', :state=>'123') %>

now the callback url will be

现在回调网址将是

http://localhost:3000/users/auth/facebook/callback?state=123&code=ReallyLongCode#_=_

Now in the callback handler you can process the state

现在在回调处理程序中,您可以处理状态

回答by Nimo

You can use the :paramsoptions, as in

您可以使用这些:params选项,如

omniauth_authorize_path(:user, :facebook, var: 'value', var2: 'value2' )

and later in the callback you can access request.env['omniauth.params']to get the hash! :)

稍后在回调中您可以访问request.env['omniauth.params']以获取哈希!:)

(copied from this answer)

(从这个答案复制)

回答by jefflunt

What you want to do is dynamically set your callback to include the partner name in the url (notthe url parameters), on a per authentication transactionbasis, depending on which partner was involved. This means setting the callback url dynamically, for each authentication request. See this blog post to get started. The callback url automatically drops the url parameters, as you've noticed, so doing this with parameters won't work.

您想要做的是动态设置您的回调,以在每个身份验证交易的基础上将合作伙伴名称包含在 url(而不是url 参数)中,具体取决于涉及哪个合作伙伴。这意味着为每个身份验证请求动态设置回调 url。请参阅此博客文章以开始使用。正如您所注意到的,回调 url 会自动删除 url 参数,因此使用参数执行此操作是行不通的。

So, if instead of trying to pass the partner name/id in as a parameter (which is dropped), you structured your routes so that the partner_idand OmniAuth providerwere part of the callback url, then you'd have something like:

因此,如果您没有尝试将合作伙伴名称/id 作为参数(已删除)传递,而是构建您的路由,以便partner_idOmniAuth 和 OmniAuthprovider成为回调 url 的一部分,那么您将拥有如下内容:

/auth/:omniauth_provider/callback/:partner_id

...where a valid callback would be something like

...有效的回调将类似于

/auth/facebook/callback/123456

...then you would know that a given callback came in from facebook, with partner id 123456

...然后你就会知道一个给定的回调来自 facebook,带有合作伙伴 ID 123456

回答by David Morales

OmniAuth already has a built-in way to know where the user was, it's called "origin" as documented here:

OmniAuth 已经有一种内置的方式来知道用户在哪里,它被称为“来源”,如此处所述:

https://github.com/intridea/omniauth/wiki/Saving-User-Location

https://github.com/intridea/omniauth/wiki/Saving-User-Location

回答by jefflunt

You know, I think I might be trying to solve this the hard way.

你知道,我想我可能正在努力解决这个问题。

Cookies might be the answer. I think you can solve this by having your login action store a cookie, and then redirecting to the proper /auth/:providerpath for authentication, and when the callback is triggered (in SessionsController#create), you just read the cookie back to know where to redirect them to.

饼干可能是答案。我认为您可以通过让您的登录操作存储一个 cookie,然后重定向到正确/auth/:provider的身份验证路径来解决这个问题,并且当回调被触发时(在SessionsController#create),您只需读回 cookie 即可知道将它们重定向到哪里。

So, right now, your "login with facebook" link (or whatever you have you in your app) probably goes to /auth/facebook. Instead if you created a custom action like

因此,现在,您的“使用 facebook 登录”链接(或您的应用程序中的任何内容)可能会转到/auth/facebook. 相反,如果您创建了一个自定义操作,例如

POST /partner_auth

...and called it with the url...

...并用网址调用它...

POST example.com/partner_auth?from=partner&provider=facebook

Then you might have a controller like:

那么你可能有一个控制器,如:

class PartnerAuth < ApplicationController
  def create
    cookies[:from] = params[:from]  # creates a cookie storing the "from" value
    redirect_to "auth/#{params[:provider]"
  end
end

Then in the SessionsController#createaction, you would have...

然后在SessionsController#create行动中,你会...

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

I tried to build a demo app to accomplish what I'd outlined in the other answer, but you're right - it was too complicated to try to dynamically inject a custom callback into the OmniAuth code. There is a configuration option to override the default callback, but it doesn't appear to be easy to set it dynamically.

我试图构建一个演示应用程序来完成我在另一个答案中概述的内容,但您是对的 - 尝试将自定义回调动态注入 OmniAuth 代码太复杂了。有一个配置选项可以覆盖默认回调,但动态设置它似乎并不容易。

So, it dawned on me that cookies would be way simpler, user-specific, and since you theoretically only need to store this frominformation for a very short time (between when the user tries to authenticate, and when the callback is triggered), it's no big deal to create a cookie, and then delete it when the callback gets hit.

所以,我突然意识到 cookie 会更简单,特定于用户,而且由于理论上您只需要将此from信息存储很短的时间(在用户尝试进行身份验证和触发回调之间),它是创建 cookie 并没有什么大不了的,然后在回调被击中时将其删除。

回答by Manmeet Singh

Use the 'state' Variable. Facebook allows the user to set a STATE variable.

使用“状态”变量。Facebook 允许用户设置 STATE 变量。

Here is how I did it, I appended the AUTH URL with ?state=providername

这是我的做法,我在 AUTH URL 后面附加了 ?state=providername

http://localhost/users/auth/facebook?state=providername

This param is returned to me at Callback as params['providername']

此参数在回调时作为 params['providername'] 返回给我

I devised the solution from the original Omniauth Path Method

我从原始的 Omniauth 路径方法中设计了解决方案

user_omniauth_authorize_path(:facebook, :display => 'page', :state=>'123') %>