Skip to content

Instantly share code, notes, and snippets.

@cmer
Forked from jamesbebbington/application_controller.rb
Created September 13, 2012 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmer/3716862 to your computer and use it in GitHub Desktop.
Save cmer/3716862 to your computer and use it in GitHub Desktop.
Rack middleware and form tag patch to insert csrf tokens into cached pages
class ApplicationController < ActionController::Base
TOKEN_PLACEHOLDER = "__CROSS_SITE_REQUEST_FORGERY_PROTECTION_TOKEN__"
after_filter :inject_csrf_token
private
def inject_csrf_token
if protect_against_forgery? && token = session['_csrf_token']
if body_with_token = response.body.gsub!(TOKEN_PLACEHOLDER, token)
response.body = body_with_token
logger.info "Injected authenticity token '#{token}'"
end
end
end
end
# Webrat integration test
require 'test_helper'
class AuthenticationTokenStoriesTest < ActionController::IntegrationTest
context "with forgery protection enabled" do
setup { ActionController::Base.allow_forgery_protection = true }
teardown { ActionController::Base.allow_forgery_protection = false }
should "inject authentication token when visiting home page" do
visit '/'
token = session['_csrf_token']
assert token.present?
assert_match Regexp.new(Regexp.escape(token)), response.body
end
end
end
# From http://www.jarrodspillers.com/2010/02/06/trying-to-use-rails-csrf-protection-on-cached-actions-rack-middleware-to-the-rescue/ and https://gist.github.com/1124982/632f1fcbe0981424128b3088ddb27a322c369cc1
module ActionView
module Helpers
module FormTagHelper
alias_method :token_tag_rails, :token_tag
def token_tag(token=nil)
if token != false && protect_against_forgery?
token ||= form_authenticity_token
tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => ApplicationController::TOKEN_PLACEHOLDER)
else
''
end
end
end
end
end
module ActionView
module Helpers
module CsrfHelper
def csrf_meta_tags
if protect_against_forgery?
[
tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token),
tag('meta', :name => 'csrf-token', :content => ApplicationController::TOKEN_PLACEHOLDER)
].join("\n").html_safe
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment