繁体   English   中英

Rails 5中的ActionController :: InvalidAuthenticityToken(仅发布)

[英]ActionController::InvalidAuthenticityToken in Rails 5 with post only

我有一个简单的应用程序,并且我正在使用Rails 5.0.0.1(该应用程序称为simpletest-它非常简单),以便找出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

这是apps / 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>

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

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

FooController#baz中的ActionController :: InvalidAuthenticityToken

我检查了很多答案。 我在apps / views / layouts / application.html.erb中确实有<%= csrf_meta_tags %>

这仅在发布时发生。 使用get可以正常工作。 但是,我需要使用post。

此外,有一个解决方案,但是对我来说这没有意义。 我可以将以下代码添加到控制器的顶部,如果格式正确,它会重新设置会话(如果我正确理解的话),然后突然起作用:

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

但格式为text / html 另外,会话没有被重置(正如我可以通过session[:qux]告诉的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修订版53290)[x86_64-linux]。

正如jphager2所提到的,这是由Rails在使用输入表单时针对CSRF(跨站点请求伪造)的保护引起的,并且可以通过使用表单帮助程序而不是简单的HTML表单来轻松解决。

您可以在这里看到Faisal对此主题的出色答案-> 了解Rails真实性令牌

问题是您需要使用表单助手,该助手将自动为authenticty_token设置隐藏的输入。

在您的视图中,您可以只使用form_tag(这是这种类型的最简单的帮助器)

<!-- in app/views/foo/bar.html.erb -->
<%= form_tag "/dobaz" do %>
  <p>Reset:
  <input type="radio" name="reset" value="true">True</input>
  <input type="radio" name="reset" value="false">False</input>
  <input type="submit"/>
<% end %>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM