CORS 정책을 통해 모든 것을 허용


100

Cors를 비활성화하려면 어떻게해야합니까? 어떤 이유로 허용 된 오리진과 헤더를 와일드 카드로 지정했지만 내 ajax 요청은 여전히 ​​내 CORS 정책에서 오리진을 허용하지 않는다고 불평합니다 ....

내 애플리케이션 컨트롤러 :

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :current_user, :cors_preflight_check
  after_filter :cors_set_access_control_headers

# For all responses in this controller, return the CORS access control headers.

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*'
  headers['Access-Control-Max-Age'] = "1728000"
end

# If this is a preflight OPTIONS request, then short-circuit the
# request, return only the necessary headers and return an empty
# text/plain.

def cors_preflight_check
  if request.method == :options
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
    headers['Access-Control-Allow-Headers'] = '*'
    headers['Access-Control-Max-Age'] = '1728000'
    render :text => '', :content_type => 'text/plain'
  end
end
  private
  # get the user currently logged in
  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
  helper_method :current_user

end

경로 :

  match "*all" => "application#cors_preflight_check", :constraints => { :method => "OPTIONS" }
  match "/alert" => "alerts#create"
  match "/alerts" => "alerts#get"
  match "/login" => "sessions#create"
  match "/logout" => "sessions#destroy"
  match "/register" => "users#create"

편집하다---

나는 또한 시도했다 :

   config.middleware.use Rack::Cors do
      allow do
        origins '*'
        resource '*', 
            :headers => :any, 
            :methods => [:get, :post, :delete, :put, :options]
      end
    end

application.rb에서

-편집 2 ---

문제는 Chrome 확장 프로그램이 CORS를 지원하지 않을 수 있다는 것입니다. CORS를 우회하는 정보를 어떻게 가져올 수 있습니까? 비행 전 확인에 어떻게 응답해야합니까?


1
"CORS 비활성화"는 아니지만 효과적으로 정책이 없습니까? 어떤 요청에도 응답 할 수없는 것 같습니다.
Nonconformist

1
이것을 localhost에서 사용합니까?
Dzung Nguyen 2013-08-11

답변:


154

rails-api를 사용한 공용 API에 대한 동일한 요구 사항이 있습니다.

또한 before 필터에 헤더를 설정했습니다. 다음과 같이 보입니다.

headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'

Access-Control-Request-Method 헤더를 놓친 것 같습니다.


이상하다. 발생한 오류에 대한 자세한 정보를 제공 할 수 있습니까?
matteo


8
Access-Control-Request-Method는 응답이 아닌 요청에 설정됩니다. developer.mozilla.org/en-US/docs/Web/HTTP/…
kuboon 2014

19

rack-cors 미들웨어를 살펴보십시오 . 구성 가능한 방식으로 CORS 헤더를 처리합니다.


2
우리는 몇 달 동안 랙 코르를 사용해 왔으며 지금까지 어떤 문제도 다루지 않았습니다. 문제가 클라이언트 측에 있지 않습니까?
Jef 2013-07-25

1
문제는 Chrome 확장 프로그램이 CORS를 지원하지 않으므로 Origin이 Null 일 수 있다는 것입니다. CORS를 완전히 비활성화하고 원본이 Null 인 요청을 포함한 모든 요청에 ​​응답하려면 어떻게해야합니까?
Nonconformist

어떤 Chrome 확장 프로그램을 사용하고 있습니까?
Jef 2013-08-08

1
Rails 백엔드와 통신하는 데 필요한 크롬 확장 프로그램을 작성 중입니다.
Nonconformist

12

간단히 Rack-cors gem https://rubygems.org/gems/rack-cors/versions/0.4.0을 추가 할 수 있습니다.

1 단계 : Gemfile에 gem 추가 :

gem 'rack-cors', :require => 'rack/cors'

그런 다음 저장하고 실행하십시오. bundle install

2 단계 : 다음을 추가하여 config / application.rb 파일을 업데이트합니다.

config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

Rails 5를 사용하지 않는 경우 자세한 내용은 https://github.com/cyu/rack-cors Specailly에서 확인할 수 있습니다 .


나를 위해 .insert_before 0중요했습니다. 사용하기 전에는 config.middleware.usepublic디렉토리에 CORS를 허용하기 전까지 만 작동했습니다 .
Tsunamis

5

특히 Chrome에서도 문제가 발생했습니다. 당신이 한 일은 본질적으로 내 응용 프로그램에서 한 것과 같습니다. 유일한 차이점은 와일드 카드가 아닌 Origin CORS 헤더에 올바른 호스트 이름으로 응답하고 있다는 것입니다. Chrome이 이것으로 까다로운 것 같습니다.

개발과 프로덕션 사이를 전환하는 것은 고통스럽기 때문에 개발 모드와 프로덕션 모드에서 도움이되는이 작은 함수를 작성했습니다. application_controller.rb다른 언급이없는 한 다음 모든 일이 내에서 발생 합니다. 최선의 솔루션이 아닐 수도 있지만 랙 코어 도 나에게 적합하지 않았고 이유를 기억할 수 없습니다.

def add_cors_headers
  origin = request.headers["Origin"]
  unless (not origin.nil?) and (origin == "http://localhost" or origin.starts_with? "http://localhost:")
    origin = "https://your.production-site.org"
  end
  headers['Access-Control-Allow-Origin'] = origin
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT, DELETE'
  allow_headers = request.headers["Access-Control-Request-Headers"]
  if allow_headers.nil?
    #shouldn't happen, but better be safe
    allow_headers = 'Origin, Authorization, Accept, Content-Type'
  end
  headers['Access-Control-Allow-Headers'] = allow_headers
  headers['Access-Control-Allow-Credentials'] = 'true'
  headers['Access-Control-Max-Age'] = '1728000'
end

그리고 application_controller.rb내 사이트에는 로그인이 필요하기 때문에이 작은 것이 있습니다.

before_filter :add_cors_headers
before_filter {authenticate_user! unless request.method == "OPTIONS"}

내에서 routes.rb나는 또한이 일이 :

match '*path', :controller => 'application', :action => 'empty', :constraints => {:method => "OPTIONS"}

이 방법은 다음과 같습니다.

def empty
  render :nothing => true
end

1
원을 닫으려고. 이 전체 CORS 엉망은 로컬 호스트 애플리케이션에서 프로덕션 백엔드를 칠 때만 발생합니다. 모든 것이 생산 중일 때 이런 일이 발생하지 않습니까?
Sebastialonso

2
백엔드와 웹앱이 동일한 URL에서 호스팅되는 경우에만. 두 개의 다른 URL에서 완전히 호스팅되는 경우 프로덕션에서도 마찬가지입니다.
Christoph Eicke 2014

3

나는 그것이 문제였던 웹 브라우저 (내 경우에는 크롬)로 밝혀지기 전에 비슷한 문제가있었습니다.

크롬을 사용하는 경우 다음과 같이 실행 해보십시오.

Windows의 경우 :

1) 데스크톱에 Chrome 바로 가기를 만듭니다. 바로 가기를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택한 다음 "바로 가기"탭으로 전환합니다.

2)“대상”필드에 다음을 추가합니다. –args –disable-web-security

Mac의 경우 터미널 창을 열고 명령 줄에서 다음을 실행합니다. ~ / Applications / Google \ Chrome.app/ –args –disable-web-security를 ​​엽니 다.

위의 정보 :

http://documentumcookbook.wordpress.com/2012/03/13/disable-cross-domain-javascript-security-in-chrome-for-development/


왜 이것이 투표를 거부 했습니까? 웹 보안이 비활성화 된 상태에서 크롬을 실행하여 해결 된 질문에서 설명한 것과 유사한 상황이 발생했습니다. 이 문제는 개발 서버를 로컬에서 실행할 때 발생합니다. 분명히 웹 보안이 항상 비활성화 된 상태에서 크롬을 실행하지 않을 것입니다.
PropertyWebBuilder

그가 상황을 올바르게 설명하기 때문에 이것은 투표를 거부해서는 안됩니다 :)
Dzung Nguyen 2013-08-11

4
나는 투표를하지 않았지만 대답에서 이것이 단지 개발 목적을위한 해결책이라는 것이 분명하지 않습니다. 이렇게하면 로컬에서 문제가 해결 될 수 있지만 웹 방문자 / 확장 프로그램 사용자가이를 수행 할 것으로 기대할 수는 없습니다. 그래서 나는 대답에서 그것을 명확히 할 것입니다.
nathanvda

1
여기에서도 투표를 거부하지는 않았지만 주어진 플래그로 실행되는 크롬의 첫 번째 인스턴스로 인해 다른 모든 인스턴스가 동일한 방식으로 실행되었습니다. 매우 조심 해야 할 것 . 잊고 즉석에서 서핑을하는 것은 너무나 쉽습니다.
dc5

2

프로덕션의 레일 애플리케이션에서이 문제가 발생했습니다. 여기에 많은 답변이 힌트를 주었고 마침내 저에게 잘 작동하는 답변을 찾도록 도와주었습니다.

저는 Nginx를 실행 중이며 my_app.conf 파일 ( my_app 은 앱 이름)을 수정하기 만하면 됩니다 . 이 파일은 다음 위치에서 찾을 수 있습니다./etc/nginx/conf.d

당신이하지 않은 경우 location / {}이미 당신은 단지 아래에 추가 할 수 있습니다 server {}다음 추가, add_header 'Access-Control-Allow-Origin' '*';아래 location / {}.

최종 형식은 다음과 같습니다.

server {
    server_name ...;
    listen ...;
    root ...;

    location / {
        add_header 'Access-Control-Allow-Origin' '*';
    }
}

-2

/config/application.rb에서 구성을 시도하십시오.

config.middleware.insert_before 0, "Rack::Cors" do
  allow do
    origins '*'
    resource '*', :headers => :any, :methods => [:get, :post, :options, :delete, :put, :patch], credentials: true
  end
end

당신은 디바이스가 Gemfile에 '랙 고르'를 추가해야 언급하는 것을 잊었다
가브리엘 Lidenor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.