OmniAuthを拡張して、ストラテジの一覧を取得する

intridea/omniauthFacebook, Twitter, GitHub, など色々なストラテジに対応しています。

List of Strategies を見ると、とても多いのが分かると思います。

OmniAuth.strategies

自分のアプリで対応しているストラテジ*1の一覧は OmniAuth.strategies で取得できます。

例えば、 intridea/omniauth-githubarunagw/omniauth-twitter を入れている場合、下記のようになります。

OmniAuth.strategies
#=> [OmniAuth::Strategies::OAuth2, OmniAuth::Strategies::GitHub, OmniAuth::Strategies::OAuth, OmniAuth::Strategies::Developer]

こうやって簡単に githubtwitter に対応したストラt・・・。

f:id:sinsoku:20160103190753p:plain:w400

OmniAuth::Strategies::Twitter が入っていない?

OmniAuth.strategies の仕組み

omniauth/strategy.rb at v1.3.1 · intridea/omniauth · GitHub

このあたりのソースコードを読んでみると、 included を使って実装されています。

module OmniAuth
  module Strategy
    def self.included(base)
      OmniAuth.strategies << base

      base.extend ClassMethods
      base.class_eval do
        option :setup, false
        option :skip_info, false
      end
    end
end

で、 omniauth-twitter のコードはこんな感じ。

omniauth-twitter/twitter.rb at v1.2.1 · arunagw/omniauth-twitter · GitHub

module OmniAuth
  module Strategies
    class Twitter < OmniAuth::Strategies::OAuth
    end
  end
end

なるほど、OmniAuth::Strategies::Twitter < OmniAuth::Strategies::OAuth < Omniauth::Strategy という継承関係になっているのが原因っぽい。

ストラテジの一覧を取得する方法

既存の included を使う方法だと大変そうだったので、ちょっと OmniAuth を拡張して別の方法で取得できるようにした。

# config/initializers/_monkey/omniauth.rb
module OmniAuth
  def self.providers
    @providers ||= []
  end

  module ProviderSaving
    def provider(klass, *args, &block)
      OmniAuth.providers << klass
      super
    end
  end
  Builder.prepend(ProviderSaving)
end

これで簡単に対応したprovider一覧が取得できる。

OmniAuth.providers
=> [:developer, :github, :twitter]

gemを簡単に上書きできて、Ruby便利ですね!💎🐒

*1:要は自分で入れた omniauth-xxxのgem