Skip to content

Instantly share code, notes, and snippets.

@carols10cents
Last active April 11, 2019 16:35
Show Gist options
  • Save carols10cents/8448420 to your computer and use it in GitHub Desktop.
Save carols10cents/8448420 to your computer and use it in GitHub Desktop.
One way to get Rails and Backbone CSRF protection working
# In your Backbone app, wherever you want -- we put this in lib/ajax_settings.coffee
define [
'backbone',
'cookie' # This is https://github.com/js-coder/cookie.js,
# we have a bower-compatible fork at https://github.com/thinkthroughmath/cookie.js
], (Backbone, cookie) ->
init: ->
# This overrides all ajax requests sent through Backbone. We could have set this in jQuery
# since Backbone ultimately calls the jQuery ajax functions, but we decided we shouldn't be
# doing ajax requests outside of Backbone anyway.
Backbone.$(document).ajaxSend (evt, xhr, settings) ->
# No, I don't know why one is underscores and one is hyphens.
xhr.setRequestHeader('X_XSRF_TOKEN', cookie.get('XSRF-TOKEN'))
# In Rails in your app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
after_filter :set_csrf_cookie_for_js
# Make sure you're not skipping this in child controllers...
protect_from_forgery
protected
# This adds to the built-in #verified_request? and allows verification if the X_XSRF_TOKEN header
# is the right token value.
def verified_request?
# You might need to inspect the headers here if things aren't working to make sure
# your web server isn't doing something funky with the headers like stripping the X or something.
super || form_authenticity_token == request.headers['X_XSRF_TOKEN']
end
private
# This sets a cookie, which is necessary if Rails isn't the one rendering your html
# (and therefore we can't use the meta tag) and if you're serving your single-page
# app from the same domain.
def set_csrf_cookie_for_js
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
end
@carols10cents
Copy link
Author

This technique is actually stolen from angular, where it's semi-built in. See this SO question

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment