2016-03-10 70 views
6

我在Rails 4应用程序中使用Devise 3.5和Omniauth。我创建了一个与Facebook的集成,允许用户将他们的Facebook帐户连接到我的应用程序。目前,当用户点击连接按钮时,它们被发送到/user/auth/facebook,然后重定向到Omniauth生成的回调URL:/user/auth/facebook/callback。我想在某些情况下手动覆盖此回调网址 - 这意味着我不想在初始化程序中覆盖它 - 具有完全合格的网址。例如,如果用户从http://www.example.com/开始,我可能想用http://app.example.com/user/auth/facebook/callback覆盖默认的回调网址。Devise/OmniAuth覆盖默认回调网址

我的应用程序具有动态子域,用户将(几乎)始终开始子域上的身份验证过程。不幸的是,Facebook似乎并不支持oauth重定向网址中的通配符,这就是为什么我希望能够检测用户是否在子域上,并将回调网址调整为我已在我的Facebook应用上列入白名单的内容,以便授权过程成功。

从我读到的,url helper omniauth_authorize_path接受附加参数作为参数传递。我试图通过一个定制的回调路径像这​​样,但没有成功:

user_omniauth_authorize_path(:facebook, callback_path: @custom_callback) 

我也试着改变callback_pathredirect_urlredirect_uri,但似乎没有任何工作。当我查看生成的链接时,确实将回调作为参数包含在url中,但是当我单击该链接时,我将重定向回默认回调url而不是自定义回调url。

+0

我需要这个功能太:( – diogopms

回答

0

以下是我解决了这个问题。我肯定还有其他的方法,但是这似乎是最简单最优雅的解决方案,我能想出。

config/routes.rb我建立了一个auth子域。我所有的Oauth连接请求将开始在不同的子域名,然后Facebook正在建立将这些用户转发回t他auth.example.com子域。

constraints AuthRedirect do 
    devise_scope :contact do 
     get '/auth/facebook/callback' => 'omniauth_callbacks#facebook' 
     post '/auth/facebook/callback' => 'omniauth_callbacks#facebook' 
    end 
end 

这是/lib/auth_redirect.rb。这只是检查子域是否为auth并捕获该流量。这是放置在我的路由列表的顶部,以便优先于其他子域。

class AuthRedirect 
    def self.matches?(request) 
     request.subdomain.present? && request.subdomain == 'auth' 
    end 
end 

然后在我的客户端,当用户点击该按钮Connect with Facebook,我送他们到/auth/facebook?contact_id=<id>。从这里Devise将他们引导到Facebook,然后将他们重定向回https://auth.example.com/

然后在OmniauthCallbacksController#facebook我可以从omniauth PARAMS拉动用户的ID如下:

auth = env["omniauth.auth"] 
contact = Contact.find(env['omniauth.params']['contact_id']) 

在这里,我能坚持凭证到数据库,并重定向用户返回到适当的子域。该解决方案避免了问题CSRF令牌,并且更重要的是不需要我使用Ruby/ERB打造omniauth授权路径用户发送到当他们点击连接按钮。

1

你试过redirect_uri吗?

user_omniauth_authorize_path(:facebook, redirect_uri: @custom_callback) 

编辑:对不起,我错过了您的文章的第二部分。

我实际上在生产中遇到了同样的问题,但它在分段环境中完美地工作。唯一的区别是关于分期回调URL其中有一个更加子域* .staging.domain.com

通过可以提供在色器件初始化文件的静态callback_url方式:

config.oaumniauth :facebook, ..., callback_url: 'url right here' 

我这个昨天在这个问题上。 要么我提供了一个静态的回调URL但Facebook提出了我的CRSF错误:

omniauth: (facebook) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected 

或者我让设计动态设置callback_url这会看起来像

https://*.domain.com/DEVISE_MODELS/auth/facebook 

在这种情况下,我得到一个直在FG登录过程中不匹配/列入白名单的回调URL。

编辑2:

好!我做到了。我可以通过通配符子域名登录oauth。

  1. 在色器件初始化
  2. 提供静态callback_url域添加到您的会话存储为: 域”。域。COM”

随着那我越来越没有CRSF错误,也不nunmatching CB网址/白名单。

希望它会为你工作!

+0

我其实解决了这个一段时间回来,忘了后我的解决方案。这真的很简单,我会用我所用的溶液更新我的答案。不幸的是我没有时间或目前的资源来测试你的解决方案,但它看起来可行,所以我会给它一个upvote。 – ACIDSTEALTH