Rspec表示,为什么机架式磁盘不能过滤传入的请求
我希望我的Rails 5 API专用应用程序,现在运行在http://localhost:3000
,只接受来自我的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配置不会阻止服务器根据Origin
请求标头的值接受请求。 你不能只通过CORS配置来做到这一点。
在服务器上配置CORS支持时,服务器执行的所有操作都只是发送Access-Control-Allow-Origin
响应头和其他CORS响应头。
CORS限制的实际执行仅由浏览器完成。 它不是由服务器强制执行的。
协议的工作方式是,无论您在服务器端进行哪种CORS配置,服务器都会继续接受来自所有客户端的请求,否则会接收来自所有客户端的请求,因此所有来源的所有客户端都会继续从服务器获取响应,就像否则就会。
因此,即使您在浏览器中发现错误,您的前端JavaScript代码中的跨源请求失败,您仍然可以在浏览器devtools中看到响应。
但仅仅因为您的浏览器可以看到响应并不意味着浏览器会将其暴露给您的前端JavaScript代码。 如果请求被发送到opts-in的服务器通过响应允许该来源的Access-Control-Allow-Origin
标头来允许请求,浏览器仅将来自跨源请求的响应暴露给在特定源运行的前端代码。
因此,对于任何具有与https://foreign.domain
匹配的Origin
请求标头的请求,问题中的配置代码段应该导致浏览器在客户端发出一条消息,说http://localhost:3000/api/v1/bodies.json
无法加载http://localhost:3000/api/v1/bodies.json
因为响应中没有Access-Control-Allow-Origin
响应标头(因为您的配置导致服务器仅在响应您列入白名单的源时发送该标头)。
但是你可以通过CORS做到这一切。 您无法通过在服务器端执行任何CORS配置来阻止服务器端接受和响应来自特定源的请求。 如果你想这样做,你需要使用除CORS配置之外的其他东西。