Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 为什么不是';我的CORS配置是否导致服务器过滤传入请求?如何使服务器只接受来自特定来源的请求?_Ruby On Rails_Rspec_Cors_Rails Api_Rack Cors - Fatal编程技术网

Ruby on rails 为什么不是';我的CORS配置是否导致服务器过滤传入请求?如何使服务器只接受来自特定来源的请求?

Ruby on rails 为什么不是';我的CORS配置是否导致服务器过滤传入请求?如何使服务器只接受来自特定来源的请求?,ruby-on-rails,rspec,cors,rails-api,rack-cors,Ruby On Rails,Rspec,Cors,Rails Api,Rack Cors,我想要我的Rails 5 API专用应用程序,现在运行在http://localhost:3000,仅接受来自my NodeJS前端应用程序的请求,目前运行于http://localhost:8888 因此,我将/config/initializers/cors.rb配置为: Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins "http://localhost:888

我想要我的Rails 5 API专用应用程序,现在运行在
http://localhost:3000
,仅接受来自my NodeJS前端应用程序的请求,目前运行于
http://localhost:8888

因此,我将
/config/initializers/cors.rb
配置为:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins "http://localhost:8888"
    resource "*",
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
我写了这个测试:

#/spec/request/cors_request_spec.rb

RSpec.feature "CORS protection", type: :request do
  it "should accept a request from a whitelisted domain" do
    get "/api/v1/bodies.json", nil, "HTTP_ORIGIN": "http://localhost:8888"
    expect(response.status).to eql(200)
  end
  it "should reject a request from a non-whitelisted domain" do
    get "/api/v1/bodies.json", nil, "HTTP_ORIGIN": "https://foreign.domain"
    expect(response.status).to eql(406)
  end
end
第一次测试如期通过。但第二个失败,响应代码为200。为什么?


(顺便说一句,我没有接受406响应代码;只有一个表示请求将无法满足的代码。)

CORS配置不会阻止服务器接受基于
源请求头值的请求。你不能仅仅通过CORS配置来做到这一点

在服务器上配置CORS支持时,服务器所做的不同只是发送
Access Control Allow Origin
响应头和其他CORS响应头

CORS限制的实际实施仅由浏览器完成。它不是由服务器强制执行的

该协议的工作方式是,无论您在服务器端进行什么CORS配置,服务器都会继续接受来自所有客户端和源的请求,因此来自所有源的所有客户端都会继续从服务器获得响应,就像它们在其他情况下一样

因此,即使您在浏览器devtools中看到来自前端JavaScript代码的跨源请求失败的错误,您仍然能够在浏览器devtools中看到响应

但是,仅仅因为您的浏览器可以看到响应,并不意味着浏览器将向您的前端JavaScript代码公开响应。如果请求发送到的服务器选择允许请求,则浏览器仅将跨源请求的响应公开给在特定源运行的前端代码,方法是使用允许该源的
Access Control Allow origin
头进行响应

因此,对于具有
来源的任何请求
请求头匹配
https://foreign.domain
,问题中的配置片段应该会导致浏览器在客户端发出一条消息,说
http://localhost:3000/api/v1/bodies.json无法加载
,因为响应中没有访问控制允许原点
响应头(因为您的配置会导致服务器仅发送该头以响应您的白名单来源)

但这就是通过CORS所能做的。你不能仅仅通过在服务器端进行任何CORS配置来阻止服务器端接受和响应来自特定来源的请求。如果你想这样做,你需要使用CORS配置以外的其他方法