I'm running Rails 4.2, Devise 3.4.1, and CanCan 1.6.10. When I try to delete resources via a standard delete button like the following one, I get signed out and redirected to the login page.
<a data-confirm="Are you sure?" class="btn-alert" rel="nofollow" data-method="delete" href="/admin/lots/6">Delete</a>
My dev log tells me it's because it "Can't verify CSRF token authenticity". The only way I can seem to get this to work is to change from a delete button to a form that posts to the delete action, but that's kind of dumb. I've done this in other Rails 4 apps so I'm pretty sure I'm doing it right.
index.html.erb
<% if can? :destroy, lot %>
<%= link_to "Delete", admin_lot_path(lot.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'btn-alert' %>
<% end %>
lots_controller.rb
class Admin::LotsController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def destroy
@lot.destroy
redirect_to admin_lots_path, notice: "Lot was successfully removed."
end
end`
Like I said, replacing the button with a form seems to work but this isn't ideal.
<%= form_for([:admin, lot], method: :delete) do |f| %>
<%= f.submit value: "Delete", class: 'btn-standard', data: {confirm: "Are you sure?"} %>
<% end %>
If I comment out before_filter :authenticate_user!
and load_and_authorize_resource
from the controller it works. I'm assuming the csrf token is not being sent along with this request like it would be in a form.
Does anybody have any ideas on what I can try? Willing to post more code if it would be helpful. This happens on all deletes in my application btw.
Update: Here's a snippet from development.log
Started DELETE "/admin/lots/6" for 127.0.0.1 at 2015-05-26 15:03:22 -0500
Processing by Admin::LotsController#destroy as HTML
Parameters: {"id"=>"6"}
Can't verify CSRF token authenticity
Use button_to
instead of link_to
.
button_to "Delete", admin_lot_path(lot.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'btn-alert'
link_to
produces this HTML which is missing the authenticity token,
<a data-confirm="Are you sure?" class="btn-alert" rel="nofollow" data-method="delete" href="/admin/lots/6">Delete</a>
while button_to
produces
<form class="button_to" method="post" action="/admin/lots/6">
<input type="hidden" name="_method" value="delete">
<input data-confirm="Are you sure?" class="btn-alert" type="submit" value="Delete">
<input type="hidden" name="authenticity_token" value="1QajBKKUzoEtUqi6ZX8DsQtT9BfvKY/WVXAr4lu4qb+iLGMkLlsviNcctlGxyq+VrsMa+U9vmb4PAdaRFDKZVQ==">
</form>
You have to pass the csrf token as a parameter, example:
link_to "Delete", admin_lot_path(id: lot.id, authenticity_token: form_authenticity_token), method: :delete, data: {confirm: "Are you sure?"}, class: 'btn-alert'
"form_authenticity_token" is a convention method that returns the CSRF token. That will authenticate the request.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With