認証機能にIPアドレス制限かけたいだけなので、いかようにもできそうですが、 オシャレに実装する方法はないかと調べてみると、以下の実装がありました。
routesのconstraints
ruby on rails 3 - How can I restrict access ActiveAdmin login page by ip? - Stack Overflow
class WhitelistConstraint def initialize @ips = Whitelist.retrieve_ips end def matches?(request) @ips.include?(request.remote_ip) end end # config/routes.rb TwitterClone::Application.routes.draw do match 'admin/' => 'admin#login', :constraints => WhitelistConstraint.new end
実装は簡単で、matches?メソッドが実装されたclassを用意し、routesのconstraintsオプションに渡すだけです。
deviseでやるには
単純にこの方法でやってみましたが、devise_for 自体がこの方法に対応してなさそうでした。
blockを使う
constraintsはblockで使うことができます。
Rails のルーティング - Railsガイド
namespace :admin do constraints subdomain: 'admin' do resources :photos end end
最終的には
こうなりました。
constraintsにはクラス自体も渡せます。この場合は、クラスメソッドとしてmatches? を実装すれば良いです。
# lib/constraints/whitelist_constraint.rb module Constraints class WhitelistConstraint WHITELIST_IPS = [ "1.2.3.4", "5.6.7.8" ].freeze def self.matches?(request) Rails.env.development? || WHITELIST_IPS.include?(request.remote_ip) end end end # config/routes.rb constraints Constraints::WhitelistConstraint do devise_for :user, :path => '', :path_names => { :sign_in => "login", :sign_out => "logout" } end
感想
constraints使ったことあんまりなかったのですが、なかなか便利でした。