簡體   English   中英

在Rails中使用omniauth-facebook的多個Facebook omniauth回調路徑

[英]Multiple Facebook omniauth callback paths using omniauth-facebook in rails

Started GET "/users/auth/facebook" ..
I, [2015-06-12T01:28:27.556166 #77305]  INFO -- omniauth: (facebook) Request phase initiated.

Started GET "/users/auth/facebook/callback?code=AQ....d8" for 127.0.0.1 at 2015-06-12 01:28:28 +0800
I, [2015-06-12T01:28:28.090435 #77305]  INFO -- omniauth: (facebook) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#facebook as HTML
  Parameters: {"code"=>"AQ..p0", "state"=>"a6..d8"}

上面是我對正在向Facebook進行omniauth請求的Rails應用程序的請求日志。 的問題是,只有一個接收的Facebook omn​​iauth響應,這是在omn​​iauth_callbacks_controller.rb回調控制器。

該方法必須處理許多情況:

  1. 新用戶->在Facebook上注冊
  2. 登錄
  3. 現有用戶->添加Facebook身份
  4. 新用戶->獲取Facebook的電子郵件作為用戶的電子郵件。

     def facebook @identity = Identity.find_for_oauth env["omniauth.auth"] @user = @identity.user || current_user if @user == current_user @user.sign_in_with << 'Facebook' if !(@user.sign_in_with.include? 'Facebook') @user.save! end if @user.nil? @user = User.create(email: @identity.email, sign_up_with: 'Facebook', sign_in_with: ['Facebook']) @identity.update_attribute(:user_id, @user.id) end .. end 

我覺得動作變得越來越胖和胖了,我想找到一種分離邏輯的方法。 有辦法嗎?

當我實現相同的功能時,我遇到了這個問題。 在這種情況下,我對路由使用了高級約束 它允許您提供一個響應matches?的對象matches? Rails應該使用的。 我可以通過FB創建帳戶並將FB帳戶與現有的自定義配置文件綁定來演示這種方法。 我們將此邏輯分為兩個動作。 由於omniauth_callbacks_controller.rb可能包含兩個操作,用於登錄/注冊和綁定Facebook帳戶。 按照RESTful命名后,它可能看起來像:

# for sign up or login with FB
def create
  @identity = Identity.find_for_oauth env["omniauth.auth"]
  # one ninja-code
end

# for binding FB account
def update
  # another ninja-code
end

因此,您可以制作兩個約束文件,例如模塊,例如

用於登錄帳戶操作,例如lib/login_facebook_contstraint.rb

class LoginFacebookConstraint

  def matches?(request)
    request.query_parameters["bind"].blank?
  end
end

並用於綁定帳戶操作,例如lib/bind_facebook_contstraint.rb

class BindFacebookConstraint

  def matches?(request)
    request.query_parameters["bind"].present?
  end
end

在綁定的情況下,您可以添加請求參數bind: true或類似的東西,例如,當我們使用Facebook Javascript SDK時,它可能看起來像這樣:

FB.login(function(response) {
  if (response.authResponse) {
    window.location = '/auth/facebook/callback?' +
      $.param({
        signed_request: response.authResponse.signedRequest,
        bind: true
      });
  }
}, {scope: 'email', info_fields: 'email'});

然后您可以在routes.rb控制路由

# Callbacks for authorized provider
get 'auth/:provider/callback', to: 'omniauth_callbacks#create',
  constraints: LoginFacebookConstraint.new
get 'auth/:provider/callback', to: 'omniauth_callbacks#update',
  constraints: BindFacebookConstraint.new

現在,如果您有一個帶有bind: true參數的請求,它將由omniauth_callbacks_controller.rbupdate操作處理,在兩種情況下,您都可以從facebook獲取參數

def auth_params
  request.env["omniauth.auth"]
end

這種方法使您可以分離出邏輯。 來源- 高級約束Facebook登錄SDK

希望我能幫助您找到更優雅的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM