リファラバック # Rails

勝手な造語なので、正確な用語があればどなたか教えてください。

gem 使うのかなと思ったけど、 raw code で何とかやれそう↓

目的

  • 或るページへは特定のページから遷移していないと NG な処理を実行すること
  • ついでに、F5 再読み込みも禁止する
    • top/index => books/index は OK
    • books/edit/:id => books/index は OK
    • peep/index => top/index (F5 GET) は NG
    • books/index => books/index は NG

方法

request.referer 調べて、目的外の referer だったら別のページに飛ばす

前提

モデル設計に意味は無いです

rails g scaffold Book title:string
rails g controller top index
rails g controller peep index

config/routes.rb

1 Foo::Application.routes.draw do
2   get 'peep/index'
3   get 'top/index'
4   resources :books
5 end 

app/controllers/top_controller.rb

1 class TopController < ApplicationController
2   def index
3   end
4 end

app/views/top/index.html.erb

1 <h3>This is TOP</h3>
2 <h1><%= flash[:error] if flash[:error] %></h1>
3 <%= link_to 'Go to book library', controller: :books, action: :index %>

app/controllers/peep_controller.rb

1 class PeepController < ApplicationController
2   def index
3   end
4 end

app/views/peep/index.html.erb

1 <h3>This is peep TOP</h3>
2 <h1><%= flash[:error] if flash[:error] %></h1>
3 <%= link_to 'Go to book library', controller: :books, action: :index %>

app/controllers/books_controller.rb

1 class BooksController < ApplicationController
2   before_action :set_book, only: [:show, :edit, :update, :destroy]
3   before_action :check_redirection
...
75 # in private
76     def check_redirection
77       unless request.referer and request.referer.gsub(/http:\/\/(.+?)\//, '') =~ (/(top\/index|books\/*)/)
78         redirect_to top_index_url, flash: {error: 'You should come from top'}
79       end 
80     end

F5 再読み込みすると request.referernil になるので、top_index_url へ redirect する

F5 再読み込みを許可するには unless 句の 第一判定子 request.referer を消す(然し、第二判定子が動作しなくなる(nil.gsubになる)ので、調整必要)

やるかやらないか別として、これは参考程度に


top/index から遷移

f:id:mat5ukawa:20140216163711p:plain

books/index へ遷移することが出来る

f:id:mat5ukawa:20140216163918p:plain

peep/index から遷移

f:id:mat5ukawa:20140216164002p:plain

失敗する(top/index へ遷移する)

f:id:mat5ukawa:20140216164022p:plain


情報元 # ありがとうございます

Railsのrequestオブジェクトの中身 refererやpath_infoを知りたい場合 - memo.yomukaku.net