【发布时间】:2013-12-12 02:02:09
【问题描述】:
快速背景
我有一个模型,其中 facility has_many managers 到 relationships。关系模型包含一个附加属性admin,它是一个布尔值。然后,对于每个设施,我都有一个页面,允许管理员/某些用户将managers 标记为admin 或不标记。他们通过复选框来做到这一点。我正在为经理使用设计。就像这个 railscast 的前 2 分钟一样,一切都差不多完成了:
http://railscasts.com/episodes/165-edit-multiple-revised?view=comments
问题
问题是,当我提交 form_tag 时,我得到:
1. 警告:无法验证 CSRF 令牌的真实性
2. 然后它会重置我的用户会话(让我退出设备),所以我必须重新登录才能继续工作。
如果我从应用程序控制器中删除 protect from forgery,一切都会顺利进行,但显然我不想这样做。
那么,如何避免 form_tag 出现这个 CSFR 问题?
表格(更新)
<%= form_tag admin_relationships_path, method: :put do %>
<table>
<tr>
<th></th>
<th>Person Name</th>
<th>Admin</th>
</tr>
<% @relationships.each do |relationship| %>
<tr>
<td><%= check_box_tag "relationship_ids[]", relationship.id %></td>
**<%= hidden_field_tag :authenticity_token, form_authenticity_token %>**
<td><%= User.find(relationship.user_id).full_name %></td>
<td><%= relationship.admin ? "Yes" : "No" %></td>
<td><%= link_to 'Remove', relationship, method: :delete, **remote: true** %></td>
</tr>
<% end %>
</table>
<%= submit_tag "Make Checked Admins" %>
<% end %>
控制器。
class RelationshipsController < ApplicationController
def destroy
@relationship = Relationship.find(params[:id])
@relationship.destroy
respond_to do |format|
format.html { redirect_to "/facilities/1679/invite", notice: " Manager has been deleted." }
format.json { head :no_content }
end
end
日志。
Started DELETE "/relationships/52" for 127.0.0.1 at 2013-11-26 14:30:11 -0500
Processing by RelationshipsController#destroy as JS
Parameters: {"id"=>"52"}
WARNING: Can't verify CSRF token authenticity
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 38 LIMIT 1
(0.1ms) BEGIN
(0.1ms) COMMIT
Relationship Load (0.2ms) SELECT `relationships`.* FROM `relationships` WHERE `relationships`.`id` = 52 LIMIT 1
(0.1ms) BEGIN
SQL (0.2ms) DELETE FROM `relationships` WHERE `relationships`.`id` = 52
(0.4ms) COMMIT
Redirected to http://localhost:3000/facilities/1679/invite
Completed 302 Found in 10ms (ActiveRecord: 1.6ms)
Started DELETE "/facilities/1679/invite" for 127.0.0.1 at 2013-11-26 14:30:11 -0500
ActionController::RoutingError (No route matches [DELETE] "/facilities/1679/invite"):
请求标头:
Accept、Accept-Encoding、Accept-Language、Connection、Cookie、Host、Origin、Referer、User-Agent、X-Requested-With
答案
正如下面的海报所提到的,我的 CSFR 令牌没有在页面上收到。虽然,我的应用程序布局和管理布局中有<%= csrf_meta_tag %>,但我实际上是在渲染应用程序布局,但表单位于设计页面上。
所以我需要将<%= csrf_meta_tag %> 代码放在devise.html.erb. 中,您可以在下面找到故障排除。
【问题讨论】:
标签: ruby-on-rails devise csrf