7

状況:

Rails 3とOmniAuthを使用して、Facebook戦略を使用して認証するアプリがあります。このアプリは、Webインターフェースとモバイルインターフェース(ala Jquery-Mobile)で同等に機能するように構築されています。

課題は、OmniAuthにFacebookのログイン画面のモバイルバージョンをモバイルデバイスに提供させ、Webバージョンをデスクトップデバイスに提供させることです。

私は答えとして置く解決策を一緒にハックしました。

4

5 に答える 5

5

実際、OmniAuth :: StrategiesはすでにRackミドルウェアであるため、さらに単純です。request_phaseメソッドをオーバーライドし、モバイルuser_agentの戦略に存在する@envインスタンス変数を確認するだけです。

module OmniAuth
  module Strategies
    class Facebook < OAuth2

      MOBILE_USER_AGENTS =  'webos|ipod|iphone|mobile'

      def request_phase
        options[:scope] ||= "email,offline_access"
        options[:display] = mobile_request? ? 'touch' : 'page'
        super
      end

      def mobile_request?
        ua = Rack::Request.new(@env).user_agent.to_s
        ua.downcase =~ Regexp.new(MOBILE_USER_AGENTS)
      end

    end
  end
end
于 2011-05-19T02:32:53.730 に答える
4

最新のdevise/omniauth(> = 1.0)の場合、config / initializers/devise.rbでこれを使用します。

FACEBOOK_SETUP_PROC = lambda do |env|
  request = Rack::Request.new(env)
  mobile_device = request.user_agent =~ /Mobile|webOS/i
  request.env['omniauth.strategy'].options[:display] = mobile_device ? "touch" : "page"
end

config.omniauth :facebook, FACEBOOK_APP_ID, FACEBOOK_APP_SECRET,
  :scope => 'email,offline_access', :setup => FACEBOOK_SETUP_PROC,
  :client_options => { :ssl => { :ca_file => Rails.root.join("config/ca-bundle.crt").to_s }}
于 2012-05-30T04:46:08.030 に答える
1

承認された回答は機能しますが、1行変更する必要がありました。omn​​iauth-facebookの現在のバージョンでは、次のように表示オプションを設定する必要がありました。

options[:authorize_params] = mobile_request? ? { :display => 'touch' } : { :display => 'page' }

私が見つけたものから「ポップアップ」、「タッチ」、または「ページ」を使用できます。

于 2011-11-11T16:51:44.960 に答える
1

最初の解決策を試しましたが、機能させることができませんでした。多くの検索の結果、Omniauthには、Facebook OAuthに必要な:displayオプションなど、引数の動的設定を可能にするオプション ":setup=>true"があることがわかりました。

まず、:setupオプションをオンにします。

config.omniauth :facebook, APP_CONFIG["fb_app_id"], APP_CONFIG["fb_app_secret"], 
    {:scope => 'email, offline_access', :setup => true}

次に、2番目のルート(セットアップルート)を追加します。

  devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } do
    get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
    get '/users/auth/:provider/setup' => 'users/omniauth_callbacks#setup'
  end

このコントローラーを追加します。装置のマニュアルに従えば、すでに持っているかもしれません。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def setup
    request.env['omniauth.strategy'].options[:display] = mobile_device? ? "touch" : "page"
    render :text => "Setup complete.", :status => 404
  end
end

このメソッドをApplicationControllerに追加します。

def mobile_device?
  if session[:mobile_param]
    session[:mobile_param] == "1"
  else
    request.user_agent =~ /Mobile|webOS/        
  end
end

終わり!

于 2011-08-14T01:03:20.563 に答える
0

私のソリューションはかなり複雑で、OmniAuthFacebook戦略の変更とRackミドルウェアの追加の両方が必要です。

まず、クラス属性を追加し、OmniAuth :: Strategies :: Facebookのメソッドを変更しました(これをomniauth.rb構成ファイルの最後に配置しましたが、libディレクトリに属しています):

module OmniAuth
  module Strategies
    class Facebook < OAuth2
      cattr_accessor :display # new

      def request_phase
        options[:scope] ||= "email,offline_access"
        options[:display] = OmniAuth::Strategies::Facebook.display || nil # new
        super
      end
    end
  end
end

次に、Rackミドルウェアを追加して、リクエストがモバイルデバイスからのものかどうかを判断し、それに応じてディスプレイを設定しました。

module Rack
  class FacebookMobileOmniauth
    def initialize(app)
      @app = app
    end

    MOBILE_USER_AGENTS =  'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
                              'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
                              'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
                              'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
                              'webos|amoi|novarra|cdm|alcatel|pocket|ipad|iphone|mobileexplorer|' +
                              'mobile'

    def call(env)
      request = Request.new(env)
      if request.user_agent.to_s.downcase =~ Regexp.new(MOBILE_USER_AGENTS)
        OmniAuth::Strategies::Facebook.display = 'touch'
      else
        OmniAuth::Strategies::Facebook.display = nil
      end   
      return @app.call(env)
    end
  end
end

そして最後に、config.ruにRackミドルウェアを追加しました。

    require ::File.expand_path('../config/environment',  __FILE__)
    use Rack::FacebookMobileOmniauth # new
    run Mystupid::Application
于 2011-04-01T19:59:41.070 に答える