RailsでBasic認証する方法と注意事項

rails-basic-2014

Railsで作成したアプリを一部限定で公開する場合など、Basic認証が手っ取り早くてよいなぁと思います。

もちろん、Webサーバ側で実装するに越したことはないのですがRailsはコントローラに標準でBasic認証のメソッドが搭載されていてめっちゃ簡単で嬉しかったのでメモ。


アプリ全体にBasic認証をかける場合

アプリケーションコントローラのbefore_filterにbasic認証用のメソッドを追加するだけ。

なんということでしょう

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  
  before_filter :basic

  # (略)

  private
  def basic
    authenticate_or_request_with_http_basic do |user, pass|
      user == 'user' && pass == 'pass'
    end
  end
end

何をしているか的な話

(基本的に)全部のコントローラがApplicationControllerを継承するので、このクラスのbefore_filterに与えたメソッドは呼ばれるたびに実行される。

適当な名前をつけて、authenticate_or_request_with_http_basicメソッドを定義し、先のbefore_filterに食わせる。 以上。

セキュリティ的にアレな件

色んなサイトで上記サンプルが示されていたけども、おわかりの通りセキュリティにアレな感じという事を覚えておく。

user == ‘XXX’ && pass == ‘XXX’ という感じで暗号化しないでそのままソースの中に保存されるので。 Apacheの.htaccessとかだと普通にパスワードは別ファイルに暗号化されて保存される。

手っ取り早く暗号化しつつBasic認証をしたい場合なにがいいかな って思って探してたら、引数にAdministrationを入れてMD5をかます方法が紹介されていた。

API dock

中身はこんな感じ

require 'digest'

 class AdminController < ApplicationController
  before_filter :authenticate

  def authenticate
    authenticate_or_request_with_http_basic('Administration') do |username, password|
      md5_of_password = Digest::MD5.hexdigest(password)
      username == 'admin' && md5_of_password == '5ebe2294ecd0e0f08eab7690d2a6ee69'
    end
  end
end

上記の場合は”secret”という文字列のmd5値を直接いれているそうです。
まぁ結局暗号化に使ってる関数とハッシュ値が共にソースに書かれているので厳しい人は「まだアカン」っていいそうですが、平文で保存するよりはまだいいのではないでしょうか。
結局こだわると色々出てきてそもそもBasic認証自体やめた方がよくねー みたいにきりがないので。

追記:2015/2/8 サーバー環境変数を使う手段をご指摘いただきました。

確かに、ソースに書くよりは良いですね。 このエントリ書いてた時全然思いもつきませんでした。 ありがとうございます。

ちなみにpublicディレクトリ以下はbasic認証かからないです

RailsでBasic認証 みたいに検索すると、上記のアプリケーションコントローラのフィルタで実装する方法しか出てこなかったから、普通にこれでOKだと思ってたんですが、(Railsわかってる人はすぐ気付くのかもしれませんが)publicディレクトリにおいた静的なコンテンツにはBasic認証かからないんですねw

本番環境にデプロイしてから気づいて焦りました(*_*;
静的なコンテンツも出したらアカンやつ入れてたのでw

よくよく考えたらpublic/hogehoge.htmlはコントローラ通さないでアクセスされるのかー
とても勉強になりました。 おわり

2014-04-13 | Posted in RailsNo Comments » 


関連記事

Comment





Comment



*