[Rails] Controllerにメソッドを追加したらBasic認証がエラーになる
Nov 7 · 3 min read
という話がありました。
※ 実際は「Controllerにメソッドを追加した」という情報はなく「何もしていないのに壊れた」話だったのですが…
見てみたら特に複雑な問題ではなかったのですが、今までRailsを使ってきた中で意外と遭遇したことがなかったので、記事にしてみました。
環境
$ ruby -v
ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-darwin18]
$ rails -v
Rails 6.0.0問題のないコントローラー
まずは壊れていない状態のコントローラーです。
メール一覧を表示する MailsController ということにします。
class MailsController < ApplicationController
http_basic_authenticate_with name: 'name', password: 'password' def index
@mails = Mail.some_scope
end
end
この状態だと…

もちろん動きます。
壊れたコントローラー
「メールのヘッダー一覧を表示して欲しい」という要件がきたので headers メソッドを追加してごにょごにょすることにしました。
class MailsController < ApplicationController
http_basic_authenticate_with name: 'name', password: 'password' def index
@mails = Mail.some_scope
end private def headers
end
end
この状態でアクセスしてみると…

無事(?)壊れました。
原因
もうおわかりかと思いますが、RailsがBasic認証の処理の中で呼んでいる headers を上書きしてしまったことが原因です。
ここでは「http_basic_authenticate_with」を使っていますが「authenticate_or_request_with_http_basic」を使っても同じ事が起きます。
また、発生するエラーはメソッドの上書き状況によって変わります。
今回は private にしていたので、「private method `headers’ called for」が発生しました。
他には、例えばpublic にして何も返していない場合は「undefined method `[]=’ for nil:NilClass」、文字列を返している場合は「string not matched」が発生します。
Railsを触り始めたばかりだと、少し躓くエラーかもしれません。
誰かのお役に立てれば幸いです。
