Rails 5中的ActionController :: InvalidAuthenticityToken仅包含帖子

时间:2016-11-29 01:57:26

标签: ruby-on-rails ruby session ruby-on-rails-5 csrf-protection

我有一个简单的应用程序,我使用Rails 5.0.0.1(该应用程序称为简单 - 它就像我可以做到的那样简单),以便在Rails 5中找出一些东西。我得到了一个奇怪的错误。

这里是config / routes.rb

Rails.application.routes.draw do
  root "foo#bar"
  get "dobaz" => "foo#bar"
  match "dobaz" => "foo#baz", via: :post
end

这是app / controllers / foo_controller.rb

class FooController < ApplicationController
  def baz
      if session[:qux].nil? || params[:reset] == "true"
        session[:qux] = 0
      else
        session[:qux] += 1
      end
      @qux = session[:qux]
      @format = request.format
      render 'bar'

  end
end

这里有app / views / foo / bar.html.erb

<p>Qux: <%= @qux %></p>
<p>Format: <%= @format %></p>
<form action="/dobaz" method="post">
<p>Reset:
<input type="radio" name="reset" value="true">True</input>
<input type="radio" name="reset" value="false">False</input>
<input type="submit"/>
</form>

我没有使用任何身份验证或登录或其他任何内容。我(显然)正在使用会话。

当我尝试实际执行应用程序时,我在异常页面上收到以下错误:

ActionController :: FooController中的InvalidAuthenticityToken#baz

我查了一堆答案。我在apps / views / layouts / application.html.erb中有<%= csrf_meta_tags %>

这只发生在帖子上。有了get,它运行正常。但是,我需要使用帖子。

此外,有一个解决方案,但它对我没有意义。我可以将以下代码添加到我的控制器的顶部,如果格式为json,那么(如果我理解的话)应该重置会话,并且突然它可以工作:

protect_from_forgery with: :reset_session, if: ->{request.format.json?}

但格式为text / html !此外,会话未被重置(我可以通过session[:qux]告诉。为什么这会产生任何影响?如果我只是使用:

protect_from_forgery with: :reset_session

它有效,但当然会重置会话。使用:null_session代替:reset_session具有相同的效果(使用和不使用if)。 我没有做什么特别的事。除了添加代码之外,我所做的只有:

rails new simpletest
[copied over Gemfile]
bundle install
rails generate controller foo bar

我在Debian 8上运行ruby 2.3.0p0(2015-12-25 revision 53290)[x86_64-linux]。

2 个答案:

答案 0 :(得分:2)

正如jphager2所说,这是由Rails&#39;引起的问题。使用输入表单时可以防止CSRF(跨站点请求伪造),并且可以使用表单助手而不是简单的HTML表单轻松解决。

你可以在这里看到费萨尔关于这个主题的好答案 - &gt; Understanding the Rails Authenticity Token

答案 1 :(得分:1)

问题是你需要使用一个表单助手,它会自动为authenticty_token设置一个隐藏的输入。

在您看来,您可以使用form_tag(这是此类型中最简单的帮助程序)

$compileProvider