Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jamesbebbington/1124982 to your computer and use it in GitHub Desktop.
Save jamesbebbington/1124982 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/
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