Ruby on Rails, React, React Native 개발자를 위한 CORS 완벽 가이드

🚦 Understanding CORS in Modern Web Development

작성자
발행일
2025년 12월 05일

핵심 요약

  • 1 CORS는 브라우저 보안 메커니즘으로, 프런트엔드와 백엔드 간의 출처가 다를 때 발생하는 무단 요청을 방지합니다.
  • 2 Ruby on Rails API에서 CORS를 올바르게 설정하려면 `rack-cors` gem을 사용하여 허용할 출처, 헤더, 메서드를 명확히 정의해야 합니다.
  • 3 React Native는 브라우저 환경이 아니므로 기본적으로 CORS 정책을 적용하지 않아, React 웹 앱과 달리 CORS 오류 없이 API 호출이 가능합니다.

도입

최신 웹 개발에서 CORS(Cross-Origin Resource Sharing)는 가장 오해받기 쉬우면서도 API 개발 시 흔히 발생하는 오류의 원인 중 하나입니다. Ruby on Rails, React, React Native와 같은 기술 스택을 사용하는 개발자들은 'CORS policy: No 'Access-Control-Allow-Origin' header present', 'Preflight response is not successful' 등의 메시지를 자주 접하게 됩니다. 본 문서는 CORS가 무엇인지, 어떻게 작동하는지, 그리고 Rails API에서 React 웹 앱 및 React Native 모바일 앱과 연동할 때 CORS를 올바르게 설정하는 방법을 심층적으로 설명합니다.

CORS란 무엇인가? CORS(Cross-Origin Resource Sharing)는 브라우저 보안 메커니즘으로, 웹사이트가 다른 웹사이트에 무단 요청을 하는 것을 방지하는 목적을 가집니다. 크로스 오리진(Cross-Origin) 요청은 프런트엔드와 백엔드의 도메인, 서브도메인, 포트, 프로토콜(HTTP/HTTPS) 중 하나라도 다를 때 발생합니다. # Preflight 요청(OPTIONS)의 중요성 특정 요청을 보내기 전에 브라우저는 특별한 OPTIONS Preflight 요청을 보냅니다. Preflight 요청이 필요한 경우는 다음과 같습니다. * 요청에 Authorization 헤더가 사용될 때 * 메서드가 GET/POST가 아닐 때 (예: PUT, PATCH, DELETE) * 프런트엔드에서 커스텀 헤더를 보낼 때 * 콘텐츠 타입이 JSON일 때 Rails는 Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Methods 헤더로 올바르게 응답해야 합니다. 그렇지 않으면 브라우저는 컨트롤러에 도달하기도 전에 요청을 차단합니다. # Ruby on Rails에서 CORS 설정 Rails는 rack-cors 미들웨어를 사용합니다. Gemfilegem 'rack-cors'를 추가하고 bundle install을 실행합니다. 이후 config/initializers/cors.rb 파일을 생성하거나 수정하여 CORS 정책을 정의합니다. ## 개발 환경 권장 설정 ruby Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'http://localhost:3000', 'http://localhost:5173' resource '*', headers: :any, expose: ['Authorization'], methods: [:get, :post, :put, :patch, :delete, :options, :head] end end * origins는 React 앱의 URL과 정확히 일치해야 합니다. * expose: ['Authorization']은 React가 JWT 또는 API 토큰을 읽을 수 있도록 허용합니다. * Preflight 요청(OPTIONS)은 자동으로 처리됩니다. # React(웹)에서의 CORS React는 브라우저 내에서 실행되므로 CORS 정책이 적용됩니다. API가 쿠키 인증을 사용하는 경우, axios.defaults.withCredentials = true;를 프런트엔드에 추가해야 합니다. # React Native에서의 CORS React Native는 브라우저가 아니며, 휴대폰의 네트워킹 스택을 사용합니다. 따라서 CORS를 강제하지 않으며, Preflight 요청을 자동으로 보내지 않습니다. 이는 React Native 앱이 CORS 오류 없이 거의 모든 API를 호출할 수 있음을 의미합니다. 개발자가 Origin 헤더를 수동으로 설정하는 경우에만 CORS 오류가 발생할 수 있습니다. # JWT, Devise 또는 토큰 인증 사용 시 Rails API가 헤더를 통해 토큰을 반환하는 경우, expose: ['Authorization']을 설정해야 합니다. 쿠키를 사용하는 경우, config.action_controller.allow_forgery_protection = false 설정과 함께 response.set_header('Authorization', token)과 같은 방식으로 토큰을 설정할 수 있습니다. # 프로덕션 환경 전체 예시 ruby Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'https://myfrontend.com', 'https://admin.myfrontend.com' resource '*', headers: :any, expose: ['Authorization'], methods: %i[get post put patch delete options head] end # React Native 및 Origin 헤더가 없는 모바일 앱 허용 allow do origins '*' resource '*', headers: :any, methods: :any end end # 일반적인 CORS 오류 및 해결 방법 * “Blocked by CORS policy”: 프런트엔드 URL이 origins에 누락된 경우입니다. * Preflight 요청이 500을 반환: 컨트롤러나 다른 Gem이 OPTIONS 요청을 가로채는 경우입니다. rack-cors가 다른 미들웨어보다 먼저 삽입되었는지 확인해야 합니다. * “No Access-Control-Allow-Origin header”: 백엔드가 CORS 헤더를 반환하지 않는 경우입니다. * 쿠키가 전송되지 않음: withCredentials: true가 설정되었는지 확인해야 합니다. 쿠키와 * 오리진은 함께 사용할 수 없으므로, 명시적인 origins를 사용해야 합니다.

결론

CORS는 오류가 아니라 브라우저의 중요한 안전 메커니즘입니다. 출처(origins), 헤더(headers), Preflight 요청의 개념을 정확히 이해한다면, CORS 설정은 예측 가능하고 관리하기 쉬워집니다. 올바르게 구성된 Rails API를 통해 React 웹 앱은 원활하게 통신하고, React Native 앱은 불필요한 제한을 피할 수 있습니다. 2025년에 풀스택 애플리케이션을 구축하는 개발자에게 CORS 마스터는 필수적인 역량입니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!