この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Ruby on Railsにて、外部からアクセスした際にもエラー画面を見れるようにしてみた
この記事は公開から1年以上が経過しています。情報が古い可能性がありますのでご注意ください。こんにちは。KBMJの本多です。
今回は実際にリリースされたプロジェクト等でアプリケーションエラーが発生した際に、開発時のようなエラーメッセージを見るための方法を紹介したいと思います。基本的に、RoRのproductionモードでは、アプリケーションエラーが発生するとlocalhost以外から接続時には
#{RAILS_ROOT}/public/500.html
を返す仕組みになっています。
これを回避する主な方法は2通りあります。
1.productionモードの設定を変更して、アプリケーションエラー時にメッセージが見れるようにする
※Rails2系及びRails3系で利用可能
#{RAILS_ROOT}/config/environments/production.rb 内の以下の行を変更
config.action_controller.consider_all_requests_local = false
↓
config.action_controller.consider_all_requests_local = true
これにより、developmentモードと同様に、外部からのアクセスでもエラーメッセージをブラウザ上に表示するようになります。
が…絶対にやってはいけません!
基本的にエラーメッセージを不特定多数の利用者の目に触れるような状態にするのはセキュリティ上非常によろしくないです。
たまにRoRではない別の言語・システムで構築されたサイトにてナマのエラーメッセージを見たことがありますが、ファイルパスやSQL等の情報が漏れる原因になるため、この方法を利用する事はやめましょう…。
一応、(物理的には)可能な方法だったので、紹介しておきました。
2.エラー発生時に特定のIPアドレス(例えば開発会社のグローバルIP)をlocalhostと「誤認」させる事で、エラーメッセージを表示するように設定する
※Rails2系で利用可能
今回紹介する方法はこちらです。
RoRの内部にて、エラー発生時の処理を”local_request?”というメソッドで判定して処理を切り替えている部分があるので、
local_request?の中身を書き換える事で、特定のIPアドレスをlocalhostであるかのように振る舞うようになります。
local_request?の元ソース(Rails 2.3.10から抜粋)は以下の通りです。
LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/].freeze
(中略)
# True if the request came from localhost, 127.0.0.1. Override this
# method if you wish to redefine the meaning of a local request to
# include remote IP addresses or other criteria.
def local_request? #:doc:
LOCALHOST.any?{ |local_ip| request.remote_addr =~ local_ip && request.remote_ip =~ local_ip }
end
これをapplication_controller.rb内にて以下のように記述する事で、指定のIPアドレスでのみエラーメッセージを見れるようになります。
private
def local_request?
[“127.0.0.1”, “(対象のIPアドレス)”].include?(request.remote_ip)
end
これにより、開発時と同様にログから追いかけるエラーメッセージをブラウザから参照できるようになり、
不具合発生時の対応が比較的楽になると思います。
残念ながらRails3系では仕様が変わって使えなくなりましたが、まだRails2系が使われているプロジェクトが多いと思いますので、是非ご活用ください。
GOOD RAILS!!