Reputation: 1175
I am a newbee to Rails. I have
<%= csrf_meta_tags %>
<%= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? %>
in my application.html.erb
. I need to post a form via ajax and I have,
data: data + "&authenticity_token="+AUTH_TOKEN,
in my ajax method for data
. I verified that both the tokens, i.e. post method header authentication token X-CSRF-Token
and the one I send Auth_TOKEN
are same. I still get Can't verify CSRF token authenticity
error. I don't want to skip the security, I need a proper way to handle this. Any idea? Thanks in advance.
Form
<h3 id="emailModalLabel">Tell Your Friends About Us</h3>
<form class="form-horizontal col-sm-12 validate" name="emailForm" id="emailForm">
<div class="form-group"><label>Your Name *</label><label class="error" for="your_name" generated="true"></label><input id="your_name" name="your_name" class="form-control required" placeholder="Your name" data-placement="top" data-trigger="manual" data-content="Must be at least 3 characters long, and must only contain letters." type="text"></div>
<div class="form-group"><label>Your E-Mail *</label><input id="your_email" name="your_email" class="form-control required email" placeholder="[email protected] (so that your friend can reply to you)" data-placement="top" data-trigger="manual" data-content="Must be a valid e-mail address ([email protected])" type="email"></div>
<div class="form-group"><label>Friend's Name *</label><input id="friend_name" name="friend_name" class="form-control required" placeholder="Your friend's name" data-placement="top" data-trigger="manual" data-content="Must be at least 3 characters long, and must only contain letters." type="text"></div>
<div class="form-group"><label>Friend's E-Mail *</label><input id="friend_email" name="friend_email" class="form-control required email" placeholder="[email protected] (so that you can email them)" data-placement="top" data-trigger="manual" data-content="Must be a valid e-mail address ([email protected])" type="email"></div>
<div class="form-group"><label>Message</label><textarea id="message" name="message" class="form-control" rows="5" placeholder="Your message here.." data-placement="top" data-trigger="manual"></textarea></div>
<div class="form-group"><p class="help-block pull-left text-danger hide" id="form-error"> The form is not valid. </p></div>
<span class="pull-right"><button class="btn col-md-5 col-sm-5 col-xs-5" data-dismiss="modal" aria-hidden="true">Cancel</button><button id="emailSubmit" type="submit" class="btn btn-default pull-right col-md-5 col-sm-5 col-xs-5">Send It!</button></span>
</form>
Ajax POST
$("#emailForm").validate({
rules:{
your_name: {required: true},
your_email: {required: true, email: true},
friend_email: {required: true, email: true},
friend_name: {required: true}
},
submitHandler: function(form) {
$("#emailSubmit").prop("disabled", true);
var data = $("form#emailForm").serialize();
$.ajax({
type: "POST",
url: "/send",//process to mail
data: data + "&authenticity_token="+AUTH_TOKEN,
success: function(msg){
if(msg['success']){
$(".successContainer").toggleClass( "hide", 1000, "easeOutSine" );
setTimeout("$('#emailModal').modal('hide')", 5000);
}else{
$(".errorContainer").toggleClass( "hide", 1000, "easeOutSine" );
}
},
error: function(){
$(".errorContainer").toggleClass( "hide", 1000, "easeOutSine" );
}
});
}
});
The data
in ajax request is serialized
so it is a string, and I am appending token to that string.
Upvotes: 0
Views: 144
Reputation: 1055
The best solution in here would be to implement a form_tag
built-in rails helper, like:
<%= form_tag '#', class: 'form-horizontal col-sm-12 validate', name: 'emailForm', id: 'emailForm' do %>
<div class="form-group">
<label>Your Name *</label>
<label class="error" for="your_name" generated="true"></label>
<%= text_field_tag "your_name", "", id: 'your_name', class: 'form-control required', placeholder: 'Your name', data: { placement: 'top', trigger: 'manual', content: 'Must be at least 3 characters long, and must only contain letters.' }%>
</div>
.
.
.
<% end %>
Notice I just included the first text_fiel_tag, you can include any other field tag by using Rails.
What's behind this? well Rails uses a token to prevent CSRF attacks.
For the ajax call you have to serialize the data from the form and then send it all along just as you are already doing it.
A good tip when working with Rails, try to always use built-in helpers, such as for the forms, images, links and so on.
Upvotes: 0