Applicationの共通コントローラ

まあ、普通の共通処理は、Applicationコントローラに書くよ、と。
フィルタの「フィルタを使った、フォーム認証」とかは、普通はココに書くよね。

まずは、ログイン機能を実装

  • アプリ内共通のApplicationコントローラ(controllers/application_controller.rb)で、こんな感じにcheck_loginedを書いてみる
    class ApplicationController < ActionController::Base
     protect_from_forgery
     before_filter :check_logined
    
     private
     def check_logined
       …中略…
     end
    end
    
  • ログインコントローラ側(controllers/login_controller.rb)は、フィルタのをそのまま使うけど、ちょっと追加
     skip_before_filter :check_logined
    
    • これを書かないと、ログイン画面表示時に、再度check_loginedが動く無限ループに陥るので、要注意!
  • あとは、フィルタで設定した、[controllers/ctrl_controller.rb]の[before_filter]を削除すれば、OK

共通の例外処理は、rescue_fromで!

  • Applicationコントローラに、こんな感じに追加して、
     rescue_from ActiveRecord::RecordNotFound, :with => :id_invalid
    
     private
     def id_invalid
       render 'shared/record_not_found', :status => 404
     end
    
  • Viewファイル(views/shared/record_not_found.html.erb)をこんな風に作って、
    <p>URL[<%= request.fullpath %>]は存在しません</p>
    
  • 存在しないIDの「http://localhost:3000/books/100」にアクセスすると、以下の表示になる、と。
    URL[/books/100]は存在しません
    
  • はー、本番(production)だと、HTTPステータス毎にエラーページ(public/404.html等)が振り分けられるから、単にエラーページの修正だけならこっちでOK!
    • とはいえ、ここはerbじゃないし、完全固定のHTMLかー。ほんとの最終的な例外だけだな、こりゃ。

CSRF対策は、protect_from_forgeryで!

  • へー、Railsだと、CSRF(Cross site request forgeries/クロスサイトリクエストフォージェリ)の対策も簡単なんだねー
  • で、やってるのは、ここね!
    • コントローラ(controllers/application_controller.rb)は、こんな感じで[protect_from_forgery]を定義してあるだけね
      class ApplicationController < ActionController::Base
       protect_from_forgery
      
    • んでもって、View(views/layouts/application.html.erb)側では、こんな感じで[csrf_meta_tags]タグを書いてあるから、
      <!DOCTYPE html>
      <html>
      <head>
       <title>Railbook</title>
       <%= stylesheet_link_tag    "application" %>
       <%= javascript_include_tag "application" %>
       <%= csrf_meta_tags %>
      </head>
      <body>
      <%= yield %>
      </body>
      </html>
      
    • こんなHTMLが出力されるんだねー。
      <html><head>
      …中略…
      <script src="/assets/application.js?body=1" type="text/javascript"></script>
      <meta content="authenticity_token" name="csrf-param" />
      <meta content="ここにはトークンの文字列ねー" name="csrf-token" />
      </head><body>
      …中略…
      <form accept-charset="UTF-8" action="/login/auth" method="post">
      <div style="margin:0;padding:0;display:inline">
        <input name="utf8" type="hidden" value="&#x2713;" />
        <input name="authenticity_token" type="hidden" value="ここにはトークンの文字列ねー" />
      </div>
      …中略…
      </form>
      </body></html>
      
      • head内のcsrf-paramとcsrf-tokenと、form内のdiv内のauthenticity_tokenで、トークンと
  • Railsでは、上記のcsrf-tokenとauthenticity_tokenが同じじゃない場合に例外を出す仕組みで対策してるんだねー。
    • ということで、開発者の鉄の掟は、以下の通りじゃ。ゆめゆめ忘れることの無きよう…
      • GETでのリンクでの更新系を行わないこと!
      • 更新系のリクエストは、ビューヘルパー(form_for/form_tag、link_toとか)を使うこと!
      • 共通のレイアウトを自分で作る場合は、必ずcsrf_meta_tagsを書くこと!

-
最終更新:2012年01月23日 07:34