【问题标题】:Ruby-on-rails test raising InvalidCrossOriginRequest when rendering a JS viewRuby-on-rails 测试在渲染 JS 视图时引发 InvalidCrossOriginRequest
【发布时间】:2017-01-27 11:01:20
【问题描述】:

我正在测试一个控制器,它具有以 .js.erb 格式呈现视图的动作。 对这些操作的测试会引发以下错误:

Minitest::UnexpectedError: ActionController::InvalidCrossOriginRequest: 安全警告:另一个站点上的嵌入标签请求了受保护的 JavaScript。如果您知道自己在做什么,请继续禁用此操作的伪造保护以允许跨域 JavaScript 嵌入。

伪造保护会导致此错误,因为当我对这些操作设置异常时它可以,但我不想禁用它。

这是我的控制器:

class TasksController < ApplicationController

  def new
    # TODO add blah later
    @task = Task.new
    render 'tasks/show_form.js.erb'
  end

  def create
    # FIXME there is bug here
    @task = Task.new(task_params)
    @task.user = current_user
    authorize! :create, @task
    save_task
  end

  def edit
    @task = Task.find(params[:id])
    authorize! :edit, @task
    render 'tasks/show_form.js.erb'
  end

  def update
    @task = Task.find(params[:id])
    @task.assign_attributes(task_params)
    authorize! :update, @task
    save_task
  end

  def destroy
    @task = Task.find(params[:id])
    authorize! :destroy, @task
    @task.destroy
    @tasks = Task.accessible_by(current_ability)
  end

  private

  def save_task
    if @task.save
      @tasks = Task.accessible_by(current_ability)
      render 'tasks/hide_form.js.erb'
    else
      render 'tasks/show_form.js.erb'
    end
  end

  def task_params
    params.require(:task).permit(:title, :note, :completed)
  end
end

这是我对这个控制器的测试:

require 'test_helper'

class TasksControllerTest < ActionDispatch::IntegrationTest
  #include Devise::Test::ControllerHelpers

  def setup
    @task = tasks(:one)
    @password = "password"
    @confirmed_user = User.create(email: "#{rand(50000)}@example.com",
                                  password: @password,
                                  confirmed_at: "2020-02-01 11:35:56")
    @unconfirmed_user = User.create(email: "#{rand(50000)}@example.com",
                                    password: @password,
                                    confirmed_at: "")
    sign_in(user: @confirmed_user, password: @password)

  end

  test "should get new" do
    get new_task_url
    assert_response :success
  end

  test "should create task" do
    assert_difference('Task.count') do

      post tasks_url, params: {task: {title: 'Dont fail test !'}}
    end

    assert_redirected_to task_url(Task.last)
  end

  test "should get edit" do
    get edit_task_url(@task)
    assert_response :success
  end

  test "should update task" do
    patch task_url(@task), params: {task: {title: 'updated'}}
    assert_redirected_to task_url(@task)
    article.reload
    assert_equal "updated", article.title
  end

  test "should destroy task" do
    assert_difference('Task.count', -1) do
      delete task_url(@task)
    end

    assert_redirected_to tasks_url
  end
end

你们中有人知道如何纠正这个错误吗?

提前谢谢你

【问题讨论】:

  • 你想在你的应用程序中故意做cors,还是意外发生?如果你想做cors,用rack-cors怎么样?
  • 我会说出乎意料,因为我只是在使用自己的资源。感谢您的帮助,我找到了解决方案:)

标签: ruby-on-rails protect-from-forgery


【解决方案1】:

您可以尝试更改您的 get 请求以使用与浏览器处理 AJAX 请求相同的机制,即 XMLHttpRequest。你可以在 Rails 测试中使用xhr

在你的情况下:

xhr :get, new_task_url

这意味着您不会为了让测试通过而绕过 Rails 默认值。

【讨论】:

  • 在最新版本的 Rails 中,现在是:get new_task_url, xhr: true
【解决方案2】:

解决方案是放在我的控制器的开头

skip_before_action :verify_authenticity_token, :only => [:edit, :new]

希望这可以帮助某人

【讨论】:

  • 我的理解是,这是禁用安全功能。其影响是,能够以某种方式破坏由该操作提供的页面的攻击者可能会从远程源请求恶意 javascript 并将其呈现给用户。
  • 我完全同意,这只是猴子补丁。
猜你喜欢
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
相关资源
最近更新 更多