Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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/
module ActionView
module Helpers
module FormTagHelper
alias_method :token_tag_rails, :token_tag
# Make all forms generate the same forgery_protection_token so that
# they can be replaced by Rack before being sent back to the user.
def token_tag
if protect_against_forgery?
tag(
:input, :type => "hidden",
:name => request_forgery_protection_token.to_s,
:value => ApplicationController::TOKEN_PLACEHOLDER
)
else
''
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment