Photo by Ali Yahya on Unsplash

[Rails] Controllerにメソッドを追加したらBasic認証がエラーになる

Tatsuya Tobioka
Ruffnote
Published in
3 min readNov 7, 2019

--

という話がありました。

※ 実際は「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を触り始めたばかりだと、少し躓くエラーかもしれません。
誰かのお役に立てれば幸いです。

--

--