【发布时间】:2017-04-12 21:36:36
【问题描述】:
我有一个简单的应用程序,我正在使用 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>
我没有使用任何身份验证或登录或其他任何东西。我(显然)正在使用会话。
当我尝试实际执行应用程序时,我在异常页面上收到以下错误:
ActionController::InvalidAuthenticityToken in FooController#baz
我已经检查了一堆答案。我在 apps/views/layouts/application.html.erb 中有 <%= csrf_meta_tags %>。
这只发生在帖子中。使用get,它工作正常。但是,我需要使用 post。
此外,还有一个解决方案,但对我来说没有意义。我可以将以下代码添加到我的控制器的顶部,如果格式是 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 修订版 53290)[x86_64-linux]。
【问题讨论】:
-
提交表单时,看到authentity_token参数了吗? (你可以在底部的错误页面上看到请求中的参数列表)
-
<input type='hidden' name='authenticity_token' value='<%= form_authenticity_token %>'>
标签: ruby-on-rails ruby session ruby-on-rails-5 csrf-protection