簡體   English   中英

js請求上的Rails ActionController::InvalidCrossOriginRequest

[英]Rails ActionController::InvalidCrossOriginRequest on a js request

我知道這已經在 SO 上提出了幾次,但我無法取得進展。 我在 Rails 5.0.7.2 上。

我每天收到數百次ActionController::InvalidCrossOriginRequest Rollbar 說它主要是由 Bingbot 引起的,它在我的用戶注冊模式上,來自 Devise。 這是一個 GET 請求,路徑是/users/sign_up

注意:這不是表格。 這是一個簡單地詢問用戶你想如何注冊的模式? Email、臉書、谷歌認證等

基本上,我的網站上有一些 javascript 操作,例如 reddit 或 stackoverflow upvote 之類的圖片。 沒有在這些鏈接上使用remote: true ,而是我有一個$.ajax調用來處理upvote,如下所示:

var token = document.querySelector('meta[name="csrf-token"]').content;

$.ajax({
  // For the upvote, type will be POST
  type: $this.data('method'),
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', token)
  },
  url: $this.data('url'),
  success: function(data) {
    // Some cleanup...
  }
}); 

一旦登出的訪問者嘗試投票,它就會觸發 ajax 請求,然后該請求被暫停(未授權)並重定向,如下所示:

Started POST "/upvotes/toggle_vote"
Processing by UpvotesController#toggle_vote as */*
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)


Started GET "/users/sign_up"
Processing by RegistrationsController#new as */*

這是我已經覆蓋的 Devise controller:

class RegistrationsController < Devise::RegistrationsController

  def new
    # ... other code        

    respond_to do |format|
      format.js   { render layout: false }
      format.html { respond_with self.resource }
    end
  end
end

/views/devise/registrations里面我有new.js.erb ,它打開了“你想如何注冊?” 模態的。

我試過的:

  • 我不認為通過添加protect_from_forgery except: :new是正確的答案(正如在類似問題中提出的那樣),因為這本質上是不安全的。

  • 我嘗試按此重新排序respond_to格式,但這會使注冊模式未打開。

  • 我試圖在 response_to 塊中拋出respond_to format.any { raise ActionController::RoutingError.new("Not Found") } catch-all ,但這並沒有解決錯誤。

  • 正如您在上面的$.ajax調用中看到的那樣,我什至嘗試設置X-CSRF-Token header。

順便說一句,完整的錯誤文本是這樣的:

ActionController::InvalidCrossOriginRequest: Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript

有任何想法嗎?

可能是因為UpvotesController#toggle_vote重定向到RegistrationsController#new並從 POST 更改為 GET,所以真實性令牌丟失了嗎?

您需要使用修改服務器中資源的 ajax 請求發送真實性令牌(發布/放置/補丁/刪除)。 通常,rails 會為您將其添加為表單中的隱藏字段。

在表單中添加它應該可以解決問題:

<% hidden_field_tag :authenticity_token, form_authenticity_token %>

幾個想法:

  1. 您不應該自己放置 csrf 令牌, jquery-railsrails-ujs (我不確定您使用的是哪一個)為您完成; 使用 rails-ujs 你需要使用Rails.ajax方法

  2. 沒有將 POST 重定向到 GET 並保留原始 POST 標頭,這意味着您確實在 GET 請求中丟失了 csrf 令牌(但是您通常不會在 GET 請求中發送或需要 CSRF 令牌,因此請檢查您為什么這樣做也許)。

對我來說,它看起來像一個 CORS 問題,就像錯誤提示我有一個 API 調用來自嵌入式 javascript 調用,該調用與您服務器上定義的域不同。 這會觸發 CORS 錯誤。 通常要修復 CORS 錯誤,您需要在允許的域列表中添加帶有網站域的 header Access-Control-Allow-Origin。 您可以使用機架 cors gem 輕松做到這一點: https://github.com/cyu/rack-cors

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM