生产中的CSRF错误:ActionController :: InvalidCrossOriginRequest

时间:2014-11-11 00:52:42

标签: ruby-on-rails ruby-on-rails-4 xss csrf

我在我的生产环境中的评论控制器上收到以下错误(在开发中工作正常)。用户流程如下:我有一个jQuery,当按下一个特定的按钮时会运行它,这会使部分文件添加一个新的注释,一个简单的表单。控制器中.js请求的respond_to方法用于new.js.erb文件。这应该相对容易,但在Rails(我使用的是Rails 4.1.1)代码或我的服务器(Rackspace Cloud Server)上出现问题。错误如下:

ActionController :: CommentsController #new中的InvalidCrossOriginRequest 安全警告:另一个站点上的嵌入式标记请求受保护的JavaScript。如果您知道自己在做什么,请继续并禁用此操作的伪造保护,以允许跨源JavaScript嵌入。

我在评论控制器中尝试了以下代码(不起作用)。它只是将浏览器中的.js文件呈现为文本字符串(javascript不起作用)。

protect_from_forgery except: :new
skip_before_action :verify_authenticity_token

我尝试在application_controller.rb文件中使用:: exception方法删除protect_from_forgery,但它不起作用(只是将浏览器中的javascript呈现为文本字符串)。

我尝试用以下代码替换" protect_from_forgery:exception"与" protect_from_forgery with :: null_session"这也不起作用(上面给出了相同的InvalidCrossOriginRequest错误)。

我的选项用完了解决这个问题。同样,它只发生在生产中。在我的本地机器上(通过localhost),一切正常。我的评论控制器的代码如下:

  class CommentsController < ApplicationController
  # before_action :set_comment, only: [:show, :edit, :update, :destroy]
  before_action :load_topic
  before_action :authenticate_user!
  # protect_from_forgery except: :new
  # skip_before_action :verify_authenticity_token

  # GET /comments
  # GET /comments.json
  def index
    @comments = Comment.all
  end

  # GET /comments/1
  # GET /comments/1.json
  def show
  end

  # GET /comments/new
  def new
    @comment = Comment.new
  end

  # GET /comments/1/edit
  def edit
  end

  # POST /comments
  # POST /comments.json
  def create
    @comment = @topic.comments.new(comment_params)
    @comment.user_id = current_user.id
    respond_to do |format|
      if @comment.save
        format.html { redirect_to @topic, notice: 'Comment was successfully created.' }
        format.json { render :show, status: :created, location: @comment }
        format.js
      else
        format.html { redirect_to @article, alert: 'Unable to add comment' }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
        format.js { render 'fail_create.js.erb'}
      end
    end
  end

  # PATCH/PUT /comments/1
  # PATCH/PUT /comments/1.json
  def update
    respond_to do |format|
      if @comment.update(comment_params)
        format.html { redirect_to @comment, notice: 'Comment was successfully updated.' }
        format.json { render :show, status: :ok, location: @comment }
      else
        format.html { render :edit }
        format.json { render json: @comment.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /comments/1
  # DELETE /comments/1.json
  def destroy
    @comment = @topic.comments.find(params[:id])
    @comment.destroy
    respond_to do |format|
      format.html { redirect_to @topic, notice: 'Comment was successfully deleted.' }
      format.json { head :no_content }
      format.js
    end
  end

  private

    def load_topic
      @topic = Topic.find(params[:topic_id])
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_comment
      @comment = Comment.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def comment_params
      params.require(:comment).permit(:topic_id, :body, :name)
    end
end

任何有关解决此问题的建议都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

这实际上发生在真实用户身上,还是您只在日志/监控中看到此错误?

当抓取工具访问您的网站时,往往会发生此错误(显然在您的开发环境中不会发生这种情况)。

documentation建议您将这些添加到控制器操作中:

skip_before_action :verify_authenticity_token, if: :json_request?

protected

def json_request?
  request.format.json?
end

但是,如果不是这种情况,我认为你确实有一个CORS问题。 2个可能的原因:

  • 您的网站是否可通过HTTP和HTTPS获取?这些是different origins!
  • 您有多个运行此网站的域名吗?尝试检查/记录请求标题,看看起源是否有任何区别。

如果您edit your hosts file并将域指向本地服务器,也可以尝试在开发中重现此内容。