Rails 4 删除按钮将我注销并导致 "Can't verify CSRF token authenticity"
Rails 4 delete button logs me out and results in "Can't verify CSRF token authenticity"
我是 运行 Rails 4.2、Devise 3.4.1 和 CanCan 1.6.10。当我尝试通过如下所示的标准删除按钮删除资源时,我被注销并重定向到登录页面。
<a data-confirm="Are you sure?" class="btn-alert" rel="nofollow" data-method="delete" href="/admin/lots/6">Delete</a>
我的开发日志告诉我这是因为 "Can't verify CSRF token authenticity"。我似乎可以让它工作的唯一方法是从删除按钮更改为 posts 到删除操作的表单,但这有点愚蠢。我已经在其他 Rails 4 个应用程序中这样做了,所以我很确定我做对了。
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`
正如我所说,用表单替换按钮似乎可行,但这并不理想。
<%= form_for([:admin, lot], method: :delete) do |f| %>
<%= f.submit value: "Delete", class: 'btn-standard', data: {confirm: "Are you sure?"} %>
<% end %>
如果我从控制器中注释掉 before_filter :authenticate_user!
和 load_and_authorize_resource
,它就可以工作。我假设 csrf 令牌没有像在表单中那样与此请求一起发送。
有人知道我可以尝试什么吗?如果有帮助,愿意 post 更多代码。顺便说一句,我的应用程序中的所有删除都会发生这种情况。
更新:这是来自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
使用 button_to
而不是 link_to
。
button_to "Delete", admin_lot_path(lot.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'btn-alert'
link_to
生成缺少真实性令牌的 HTML,
<a data-confirm="Are you sure?" class="btn-alert" rel="nofollow" data-method="delete" href="/admin/lots/6">Delete</a>
而 button_to
产生
<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>
您必须将 csrf 令牌作为参数传递,示例:
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" 是 returns CSRF token 的约定方法。这将验证请求。
根据 ActionController documentation 所有控制器操作都受到 CSRF(跨站请求伪造)攻击的保护,因此您需要在呈现的 HTML 中包含您的令牌,或者另一种方式是包含
protect_from_forgery unless: -> { request.format.json? }
在您的 应用程序控制器 中。这个问题不会出现在 GET 请求中,因为你没有在那里操作数据,而是出现在 POST,DELETE,PATCH 方法中.
我是 运行 Rails 4.2、Devise 3.4.1 和 CanCan 1.6.10。当我尝试通过如下所示的标准删除按钮删除资源时,我被注销并重定向到登录页面。
<a data-confirm="Are you sure?" class="btn-alert" rel="nofollow" data-method="delete" href="/admin/lots/6">Delete</a>
我的开发日志告诉我这是因为 "Can't verify CSRF token authenticity"。我似乎可以让它工作的唯一方法是从删除按钮更改为 posts 到删除操作的表单,但这有点愚蠢。我已经在其他 Rails 4 个应用程序中这样做了,所以我很确定我做对了。
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`
正如我所说,用表单替换按钮似乎可行,但这并不理想。
<%= form_for([:admin, lot], method: :delete) do |f| %>
<%= f.submit value: "Delete", class: 'btn-standard', data: {confirm: "Are you sure?"} %>
<% end %>
如果我从控制器中注释掉 before_filter :authenticate_user!
和 load_and_authorize_resource
,它就可以工作。我假设 csrf 令牌没有像在表单中那样与此请求一起发送。
有人知道我可以尝试什么吗?如果有帮助,愿意 post 更多代码。顺便说一句,我的应用程序中的所有删除都会发生这种情况。
更新:这是来自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
使用 button_to
而不是 link_to
。
button_to "Delete", admin_lot_path(lot.id), method: :delete, data: {confirm: "Are you sure?"}, class: 'btn-alert'
link_to
生成缺少真实性令牌的 HTML,
<a data-confirm="Are you sure?" class="btn-alert" rel="nofollow" data-method="delete" href="/admin/lots/6">Delete</a>
而 button_to
产生
<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>
您必须将 csrf 令牌作为参数传递,示例:
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" 是 returns CSRF token 的约定方法。这将验证请求。
根据 ActionController documentation 所有控制器操作都受到 CSRF(跨站请求伪造)攻击的保护,因此您需要在呈现的 HTML 中包含您的令牌,或者另一种方式是包含
protect_from_forgery unless: -> { request.format.json? }
在您的 应用程序控制器 中。这个问题不会出现在 GET 请求中,因为你没有在那里操作数据,而是出现在 POST,DELETE,PATCH 方法中.