Rails - How to add CSRF Protection to forms created in javascript?
Solution 1
If you have <%= csrf_meta_tag %>
in your layout somewhere and that is accessible to you from the js, then you can access it using $('meta[name="csrf-token"]')
See http://eunikorn.blogspot.com/2011/07/working-with-backbonejs-in-harmony-with.html for an idea on how to hack in csrf support into each backbone request
Solution 2
Best way I solved this, inside the form:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
Update:
It looks like the form_authenticity_token
is private for controllers in the newer rails versions.
If that's the case for you, what I suggest is: declare a variable in a controller like:
@form_token = form_authenticity_token
and use it in the view you are looking for.
Solution 3
You can prepend the csrf token to every form that uses 'post' or 'delete'. Here it is in coffeescript:
$ ->
for f in $("form")
if f.method == 'post' or f.method == 'delete'
$(f).prepend("<input type='hidden' name='authenticity_token' value='" + token + "'>")
Make sure you have <%= csrf_meta_tags %> in your layout. It should already be in the standard 'application' layout, but add it if you're using a different layout.
Solution 4
I have a form inside a Vue component in a Rails 6 app.
To my surprise, it was sufficient to include a hidden input with the name authenticity_token
within the Vue template and on page load, Rails filled out the value with a CSRF protection token.
E.g.
<template>
<div id="app">
<form
action="/submit"
method="post"
@submit.prevent="onSubmit"
>
<input
type="hidden"
name="authenticity_token"
value=""
>
<!-- rest of form -->
</form>
</div>
</template>
Which gets rendered as:
<div id="app">
<form action="/submit" method="post">
<input type="hidden" name="authenticity_token" value="zl9PJiE...">
...
</form>
</div>
CamelCamelCamel
Updated on September 05, 2020Comments
-
CamelCamelCamel over 3 years
I'm using backbone.js and it works great. but the forms I'm creating as a javascript template lacks the rails csrf protection token. How do I add it to templates I'm creating in javascript?
-
Chris Pfohl over 11 yearsSee gist.github.com/3482636 for another example of how this can be hacked in. I have no idea if it's the same.
-
Franklin Yu over 7 yearsIt works, but why? Isn't
form_authenticity_token
private in the controller? -
juliangonzalez over 7 yearsWhere is
token
declared? -
juliangonzalez over 7 yearsThis doesnt work for me Rails 4.2.2. I get:
undefined local variable or method 'form_authenticity_token' for #<#<Class:0x007ff80b1d36d8>:0x007ff7eec39b58>
-
lucianosousa over 7 yearsHey guys, looks like
form_authenticity_token
is private for controllers like Franklin said. What I saw as a suggestion was declare a variable in a controller@form_token = form_authenticity_token
and use it in the view. -
sameers over 6 yearsWhat @suga_shane means by writing, "make sure you have
<%= csrf_meta_tags %>
", is that this Rails helper generates a token for you and inserts it in the HTMLhead
. The token is thecontent
attribute in the<meta>
tag with namecsrf-token
. -
Jared Menard over 6 yearsThis works for me in rails 4.2.5. Note: this form was generated in ERB and not in JS.
-
Meekohi over 5 yearsSpecifically:
$.ajax(data: {authenticity_token: $('meta[name="csrf-token"]').attr("content")})