カクカクしかじか

技術的なアレコレ

Railsでミドルウェアの読み込み順序を変える方法

ミドルウェアって?

OSとアプリケーションの間に入って動作するソフトウェアのこと。

現在のRailsアプリのミドルウェアの状態を知りたいときは?

bundle exec rake middleware コマンドをアプリディレクトリで打てばOK
(Rails4系も5系も同じ)

$ bundle exec rake middleware
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ContentSecurityPolicy::Middleware
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Rack::TempfileReaper
run Taskleaf::Application.routes

コード例を軽く解説

ここでコンソールに表示されたものがRailsアプリの動作に関わるミドルウェアたちです。 Railsにパッチを無理やり当てないとダメなとき、このミドルウェアの読み込み順序をいじる場合があります。 (例えば、FacebookTwitterのOauthが走るより早く特定のキーを無理やり書き換える必要があるなど。)
ここでの読み込まれる順序は上に表示されるものほど先に読み込まれています。
ちなみに上記のコード例では、Rack::Sendfileが一番初めに読み込まれて、Rack::TempfileReaperが一番最後に読み込まれてRailsが起動することになります。

そもそもミドルウェアってどう読み込むの?

config.middleware.useの引数に読み込みたいミドルウェアを指定します!
※ initializers配下のファイルであれば、ある程度どこに書いてもOKっぽい?けどカオスになるので、/config/application.rbに書くのが安全な気がします。

/config/application.rb

config.middleware.use Rack::Attack

【本題】:ミドルウェアの読み込み順序を変える方法

例) ActionDispatch::Session::HogeをActionDispatch::Fugaより先に読み込みたい場合

/config/application.rb

config.middleware.insert_before ::ActionDispatch::Fuga, ActionDispatch::Session::Hoge

beforeの構文(config.middleware.insert_before)

config.middleware.insert_before 基準となるミドルウェア, 前に持っていきたいミドルウェア

afterも可能(config.middleware.insert_after)

config.middleware.insert_after ::ActionDispatch::Fuga, ActionDispatch::Session::Hoge

最後に

用法容量を正しく守ってモンキーパッチを当てましょう!