Top > Ruby on Railsあれこれ > ボタンの2度押し対策
#freeze
#contents

* 内容 [#e4dfa4c9]
** 事前準備 [#jb93211a]
*** プラグインの準備 [#qb9a4c9d]
[[色々なプラグイン>Ruby on Railsあれこれ/色々なプラグイン]]の「5.ダブルサブミット(2重登録)防止」をインストールして下さい(既にされていれば、再インストール必要はありません)。

** 概要 [#s38efaaa]
登録ボタンのダブルクリックや、ページリロードなどで、情報が2重に登録されてしまうことを防ぐサンプルです。

初めは、Railsに標準装備されているCSRF(Cross-Site Request Forgery)防止機能で出来るかなと思っていたのですが、駄目なんですね。CSRF防止機能で生成されるトークンキーは1セッション:1キーなので、ブラウザが起動している限りトークンが変わらないんです。よって、登録ボタンのダブルクリックや、ページリロードによる2重登録は防げません。

入力画面(index.html.erb)&br;
&ref(tutorial_dbs_1.jpg);&br;
↓&br;
結果画面(result.html.erb)&br;
&ref(tutorial_dbs_2.jpg);&br;
↓(ここで、リロードしてみましょう)&br;
以下のような、不正なトークンの場合の画面になります&br;
&ref(tutorial_dbs_3.jpg);&br;

** サンプルのポイント [#q7d3bdfe]
・double_submit_protectionを使用します。&br;
-[[github DianthuDia / double_submit_protection:http://github.com/DianthuDia/double_submit_protection/tree/master]]&br;

** サンプルの使い方 [#w32269a0]
サンプルはあらかじめ用意していないので、以降の項目を参照にして、自分で作成しなければいけません。作成後に、ブラウザからhttp://127.0.0.1:3000/tokenにアクセスしましょう(ポート番号"3000"は適宜、環境に応じて読み替えて下さい)。

** ファイル構成 [#ja975188]
本項で作成するファイル&br;
|ファイル名|種類|h
|index.html.erb|ビュー|
|result.html.erb|ビュー|
|token_controller.rb|コントローラー|

** ビュー(初期画面) [#dcff12ff]
初期画面を作成しましょう。
"ror-tutorial\app\views\token\index.html.erb"ファイルを以下の内容で作成します。
#code(ruby){{
<html>
<head>
<title>Tutorial: Token</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <%= stylesheet_link_tag 'ror' %>
</head>
<body>
<h2>Tutorial: Token</h2>
 
<%= @message %>
<% form_tag :action => 'submit' do %>
  <%= submit_tag "サブミット" %>
  
  <%# 1)ダブルサブミット防止用トークンを出力します%>
  <%= double_submit_token %>
<% end %>
</body>
</html>
}}

1)ダブルサブミット防止用トークンを出力します&br;
"<%= double_submit_token %>"が以下のようなHTMLになります。
#code(ruby){{
<input id="submit_token" name="submit_token" type="hidden" value="6aeffb7b29f4122d87d84e4f9f2b5486" />
}}

** ビュー(結果画面) [#j3e951dc]
結果画面を作成しましょう。
"ror-tutorial\app\views\token\result.html.erb"ファイルを以下の内容で作成します。
#code(ruby){{
<html>
<head>
<title>Tutorial: Token</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <%= stylesheet_link_tag 'ror' %>
</head>
<body>
<h2>Tutorial: Token</h2>
<%= @message %>
</body>
</html>
}}

** コントローラー [#saf60d86]
"ror-tutorial\app\controllers\token_controller.rb"ファイルを以下の内容で作成します。
#code(ruby){{
class TokenController < ApplicationController
 
  #入力画面表示
  def index
    render :action => 'index.html.erb'
  end
  
  #結果画面表示
  def submit
    #不正なトークンかチェックする
    if double_submit?
      render(:text => '不正なトークンです〜')
      return
    end
    @message = "正常なトークンでしたぁ〜"
    render :action => 'result.html.erb'
  end
  
end
}}

    ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS