deviseにおけるStrategyパターン

以下の記事でStrategyパターンの例として紹介されていたdeviseを最近使用したので、どのようにStrategyパターンが使用されているかを調べました。

Rubyでのデザインパターンの使用例を説明する!! - エニグモ開発者ブログ

Strategyパターンとは

ある問題に対するアルゴリズムを他の部分と分離して、状況に応じてアルゴリズムを切り替えられるようにするデザインパターン

deviseにおけるStrategyパターン

deviseはWardenという認証のフレームワークを元に作られています。 Warden::Strategies::Baseのサブクラスを定義することで独自の認証方法を実装することができます。

Warden::Strategies::Base

deviseの場合はDevise::Strategies::BaseWarden::Strategies::Baseを継承しています。

module Devise
  module Strategies
    class Base < ::Warden::Strategies::Base
      (略)
    end
  end
end

さらにその下に、Devise::Strategies::Baseを継承しているDevise::Strategies::Authenticatableクラスが存在します。

module Devise
  module Strategies
    class Authenticatable < Base
      # このクラスが各認証方法が実装されているクラスのベースになる
    end
  end
end

deviseの認証方法が実装されているクラスはさらに一階層下のDatabaseAuthenticatableクラスと、Rememberableクラスです。

module Devise
  module Strategies
    # Default strategy for signing in a user, based on their email and password in the database.
    class DatabaseAuthenticatable < Authenticatable
      # デフォルトの認証方法。DBに登録されているemailとパスワードを使って認証を行う
    end
  end
end
module Devise
  module Strategies
    class Rememberable < Authenticatable
      # cookieの値を使って認証を行う
    end
  end
end

独自の認証方法に切り替える場合は

  • config/initializers/devise.rbに独自のStrategyの設定方法を追加
# hoge_authenticatableという独自のStrategyを追加する
config.warden do |manager|
    manager.default_strategies(scope: :user).unshift :hoge_authenticatable
    manager.strategies.add(:hoge_authenticatable,
                           Devise::Strategies::HogeAuthenticatable)
end
  • 独自のStrategyクラスを作成する
require 'devise/strategies/authenticatable'

module Devise
  module Strategies
    class HogeAuthenticatable < Authenticatable
    end
  end
end

参考