[Rails] Controllerにメソッドを追加したらBasic認証がエラーになる
という話がありました。
※ 実際は「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を触り始めたばかりだと、少し躓くエラーかもしれません。
誰かのお役に立てれば幸いです。