簡體   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