login_requiredでベーシック認証ダイアログ

Railsで、少し古いユーザ認証プラグイン(Restful Authentication)を使っていて、ブラウザが IEOpera、WebTVで、『before_filter login_required』に引っかかったときのこと。超限定的な話題。

状況

例えば、Usersコントローラの showにアクセスがある場合、事前にログインしていなければログインページに飛ばすということはよくあることです。

class UsersController < ApplicationController
  before_filter :login_required, :only => [:show, :edit, :update]

『login_required』はどこで定義されているかというと、ここ(↓)です。少し古いソースです。

def login_required
  authorized? || access_denied
end

def access_denied
  respond_to do |format|
    format.html do
      store_location
      redirect_to new_session_path
    end
    format.any do
      request_http_basic_authentication 'Web Password'
    end
  end
end
RAILS_ROOT/lib/authenticated_system.rb

ここを見る限り、通常(HTML)のアクセスであれば、『redirect_to new_session_path』でログインページへ飛んでいくはずですが、IE(Opera、WebTVもそうらしいですが未確認)だと、format.anyの方に引っかかってこのようなベーシック認証画面が出てしまいます。まずいですね。

対処

最新版(たぶん)の『authenticated_system.rb』は format.anyが format.any(:json, :xml)になっていて、IEでも大丈夫でした。(:json、:xml以外のプロトコルを使う必要がある人は各自追加)

  # Add any other API formats here.  (Some browsers, notably IE6, send Accept: */* and trigger 
  # the 'format.any' block incorrectly. See http://bit.ly/ie6_borken or http://bit.ly/ie6_borken2
  # for a workaround.)
  format.any(:json, :xml) do
    request_http_basic_authentication 'Web Password'
  end

プラグインを自分のプロジェクトの libに取り込むとなかなかメンテしないと思いますが、こういうバグFIXもあるので定期的にチェックしないと、という教訓でした。