首页 > 解决方案 > 使用 form_with 时出现“ActionController::InvalidAuthenticityToken”错误

问题描述

我有一个看起来像这样的表格:

  <%= form_with(url: star.starname, method: :post, local: true) do |f| %> 
    <% star.availabilities.each do |avail| %> 

    <%= f.label avail.time_slot %> 
      <%= radio_button_tag(:time_slot, avail.time_slot) %> <br>
    <% end %> 

  <%= f.submit "Create" %>
  <% end %> 

表单提交后立即:

在此处输入图像描述

笔记:

更多的错误信息:

Started POST "/talljohn" for ::1 at 2020-09-16 10:06:21 +1000
Processing by StarsController#book as HTML
  Parameters: {"authenticity_token"=>"P++4a+giwUBqZgCLfMwqKpMu0EGitd8zTOi5RWsnxpKlNcjiuU6hd3ebbIC/IOxlL74RJIvrq+yDuA1ZtfcvFw==", "time_slot"=>"2020-09-16 01:00:00 UTC", "commit"=>"Create", "starname"=>"talljohn"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 655)


  
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
  
actionpack (6.0.3.2) lib/action_controller/metal/request_forgery_protection.rb:215:in `handle_unverified_request'
actionpack (6.0.3.2) lib/action_controller/metal/request_forgery_protection.rb:247:in `handle_unverified_request'
devise (4.7.2) lib/devise/controllers/helpers.rb:255:in `handle_unverified_request'
actionpack (6.0.3.2) lib/action_controller/metal/request_forgery_protection.rb:242:in `verify_authenticity_token'
activesupport (6.0.3.2) lib/active_support/callbacks.rb:428:in `block in make_lambda'
activesupport (6.0.3.2) lib/active_support/callbacks.rb:200:in `block (2 levels) in halting'
actionpack (6.0.3.2) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
activesupport (6.0.3.2) lib/active_support/callbacks.rb:201:in `block in halting'

更新

我恢复到表单的最后一个工作版本,它与上面完全相同,但没有, local: true. 然后它突然起作用了!(没有错误)。

我认为local: true(或remote: false)只是关闭了 ajax 表单提交。所以我不明白为什么这会产生任何影响(或与 CSRF 有任何关系),这两个方面似乎是不相关的,并且不清楚为什么这两个概念会对彼此产生任何影响

更新 2

后来我意识到另一个未触及的以前工作的表单也产生了这个错误。它没有以任何方式改变。我在chrome incognito中尝试过,它产生了错误。半小时后(没有更改任何代码)我在同一个浏览器中再次尝试它并且它工作。这种(非常)奇怪的行为让我觉得这与会话、cookie 或缓存有关。如果我进一步了解,我会报告

更新 3

在阅读了莎拉添加protect_from_forgery prepend: true到应用程序控制器的解决方案后(我在之前和之后都尝试过before_action :authenticate_user!),日志中出现相同的错误消息,POST 请求没有被执行,但应用程序重定向到主页。即在 POST 上我看到:

Can't verify CSRF token authenticity.
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms | Allocations: 444)


Started GET "/users/sign_in" for ::1 at 2020-09-17 21:08:42 +1000
Processing by Devise::SessionsController#new as HTML
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.5ms | Allocations: 1900)

更新 4

我试图手动清除 rails 片段缓存(使用Rails.cache.clear )。但是清除片段缓存之前/之后的结果完全相同。

标签: ruby-on-railsruby-on-rails-6

解决方案


我记得遇到过这样的事情并在解决它protect_from_forgery prepend: true之前添加任何用户身份验证。ApplicationController


推荐阅读