Reputation: 891
I am submitting a form in Rails4 from Modal. This solution was working fine in Rails 3.x
The code is as following:
<div class="modal fade" id="copy-product-addons">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4>Copy Add-Ons From:</h4>
</div>
<div class="modal-body">
<form id="addons-copy" method="POST" action="<%= copy_addons_product_path(@product) %>">
<%= select_tag "from", options_from_collection_for_select(@shop.enabled_products - [@product], 'id', 'name'), :class => "form-control %>
</form>
</div>
<div class="modal-footer">
<a href="#" class="btn btn-danger" data-dismiss="modal">Cancel</a>
<a href="#" onclick="$('#addons-copy').submit(); return false;" class="btn btn-primary">Copy Add-ons</a>
</div>
</div>
</div>
</div>
<% end %>
As a response, instead of executing specific action it re-directs me to Login page by login me out.
The response in terminal looks like:
> Started POST "/products/10168/copy_addons" for 127.0.0.1 at 2016-01-10
> 21:19:10 +0100 Processing by ProductsController#copy_addons as HTML
> Parameters: {"from"=>"10130", "id"=>"10168"} Can't verify CSRF token
> authenticity Redirected to http://myr-d.dev/login Filter chain
> halted as :require_login rendered or redirected
Thank you
Upvotes: 1
Views: 1870
Reputation: 1434
In Rails 4, there are conventions that prevent CSRF attacks for HTML requests. This SO post explains the general concept well: Understanding the Rails Authenticity Token
It looks like your Controller is checking for a CSRF token, but your form is not sending one. That is because you are using a manual <form>
tag in your view, which does not contain the required hidden token.
If you use Rails form_tag
helper method, Rails will automatically generate the authenticity token for you that will then be sent along as part of the form:
<div class="modal-body">
<%= form_tag(copy_addons_product_path(@product), id: "addons-copy") do %>
<%= select_tag "from", options_from_collection_for_select(@shop.enabled_products - [@product], 'id', 'name'), :class => "form-control %>
<% end -%>
</div>
If you inspect the HTML that will get generated from this, you'll see a hidden input tag; something like this:
<input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
This is how the token gets sent as part of the form. Then your Controller will compare this with the current token to verify there is no CSRF attempt, and you should no longer encounter this error.
Upvotes: 6