鍋の底

雑多な記録

OmniAuthで独自認証機構を作る

OmniAuthのプラグイン

TwitterFacebookの認証を利用するのに、OmniAuth というライブラリがあります。 Webで検索してもすぐに情報が出てくるので、メジャーなのでしょう。

この OmniAuth の特徴の一つは、プラグイン形式により様々な認証機構に対応できることでしょう。 このプラグインを Strategy といいます。

List of Strategies · intridea/omniauth Wiki · GitHub には対応するStrategyが列挙され、さまざまな認証機構に対応していることがわかります。 また、Strategy Contribution Guide · intridea/omniauth Wiki · GitHub に沿って Strategy の開発もできます。 なので、既存の Strategy がなければ、どんなマイナーな認証機構でも自分で作ってしまえばいいのです。

このStrategyですが、Strategy Contribution Guide · intridea/omniauth Wiki · GitHubを見ればわかるとはいえ、日本語の情報は見つかりませんでした。 なので、備忘録を兼ねて書き出しておくことにします。

Strategyの基本構造

さて、Strategyの基本構造としては次の形となります。(hogeという認証機構向け)

modulerequire "omniauth"
OmniAuth
  module Strategies
    class Hoge
      include OmniAuth::Strategy

      # 定義部
      args [:hoge]
      option :fuga
      option :moge, "Moge"

      # リクエストフェーズ
      def request_phase
        ……
      end

      # コールバックフェーズ
      uid do
        # ユーザIDを返す
      end
      info do
        # 認証情報をハッシュで返す
      end
      credentials do
        # 認証情報をハッシュで返す
      end
      extra do
        # 認証情報をハッシュで返す
      end

    end
  end
end

ここから以下のことがわかります。

  • OmniAuth::Strategyをincludeした OmniAuth::Strategies::Hoge クラスを実装する。
  • 定義部、リクエストフェーズ、コールバックフェーズがある。

定義部

各appで利用する際のパラメータを、ここで定義します。 例えば、Railsで利用する際には以下のようになります。

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :hoge, "hogege", :fuga=> "Fuga-"
end

必須のパラメータは、args で引数として定義し、必須ではないパラメータは、option で定義するといいでしょう。 どちらもコード内では options.hogeのようにアクセスできます。

リクエストフェーズ

通常 /auth/hoge というURLで受け取る、認証の出発点となります。 OAuthのように、別のURLにリダイレクトしたり、ユーザIDとパスワードを入力するフォームを表示して入力を促したりできます。

このURLに渡されたリクエストパラメータは、session経由でコールバックフェーズで読み出せます。 env["omniauth.params"]にアクセスしてください。

コールバックフェーズ

Auth Hash Schema · intridea/omniauth Wiki · GitHub に定義されている、Auth Hash を定義するフェーズです。ここに認証プロバイダから受け取った認証情報やユーザの詳細情報が含まれています。このAuth Hashは、env['omniauth.auth']から読み出せます。

userとinfoは必ず定義してください。env['omniauth.auth'].user や env['omniauth.auth'].info で内容にアクセスできます。

コールバックURLは、appで定義してください。

最後に

List of Strategies · intridea/omniauth Wiki · GitHub には、たくさんのStrategyがあるのですが、OAuthのものが多く、POSTやHTTPヘッダで渡ってくるタイプのものが見つけられませんでした。 そこで、自分で実装することにしたのですが、定義の列挙のような形で実現できました。

認証はOmniAuthにやってもらい、認可についてはapp内でするという住み分けにもなるかと思います。