본문 바로가기
카테고리 없음

CORS 와 SOP 개념 정리

by jyee 2025. 2. 2.
728x90
반응형

1. SOP 동일 출처 정책? 

▶ SOP(Same-Origin Policy)

웹브라우저의 보안정책으로, 서로 다른 출처의 리소스 간 데이터 접근을 제한한다.

동일 출처란?

먼저 출처(Origin): 프로토콜 + 도메인 + 포트로 구성되어 있다.  이 세가지가 동일해야지만 동일 출처이다! 

▶ SOP의 역할

  • 보안강화 : 동일출처 정책은 위험할 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여주는 역할을 수행한다 만약 이런 제약이 없다면 CSRF (Cross-Site Request Forgery) 나 XSS(Cross-Site Scripting)등의 공격에 매우 취약해질 가능성이 생긴다.
  • 자동 로그인 예시: 브라우저는 로그인시 발급된 토큰이나 쿠키를 저장한다. 동일한 출처에 재접속 시 이 정보가 자동으로 포함되어 자동 로그인이 가능하다.  

2. CORS란?

 CORS(Cross-Origin Resource Sharing) SOP의 제약을 안전하게 우회할 수 있는 방법이다.

 

▶ CORS의 필요성

  • SOP로 인해 다른 출처의 리소스에 접근할 수 없지만, 실제로는 API 요청 등으로 다른 서버와 통신할 필요가 많다.
  • CORS는 서버가 특정 출처에 대해 접근을 허용하도록 설정할 수 있는 방식이다.

▶ CORS 동작 원리

  1. 클라이언트가 다른 출처에 요청을 보냄.
  2. 서버는 요청의 헤더에 포함된 Origin 값을 확인.
  3. 서버가 해당 Origin을 허용했다면, 브라우저는 요청을 정상적으로 처리.
  4. 허용되지 않았다면, 브라우저는 CORS 에러를 발생시킴.

3. CORS의 접근제어 시나리오

1. 프리플라이트 요청(Preflight Request)

  • 조건: 요청에 커스텀 헤더, PUT/DELETE 메서드, 혹은 Content-Typeapplication/json인 경우.
  • 동작:
    1. 브라우저가 OPTIONS 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 사전 요청을 보냄.
    2. 서버가 허용하면 본 요청(Actual Request)을 진행.

2. 단순 요청(Simple Request)

  • 조건: GET, POST, HEAD 메서드를 사용하고, 커스텀 헤더가 없는 경우.
  • 특징: 별도의 사전 요청 없이 바로 서버에 요청.

3. 인증 정보 포함 요청(Credentialed Request)

  • 특징: 쿠키나 인증 토큰을 포함한 요청.
  • 서버 설정 필요: 서버는 Access-Control-Allow-Credentials: true와 함께 특정 출처를 허용해야 함.

3-1. 프리플라이트 요청과 응답의 필수 헤더

프리플라이트 요청과 응답 시 반드시 포함되어야 할 헤더들이 있다.

프리플라이트 요청 예시

OPTIONS /doc HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

요청 헤더 설명

  • Origin: 요청의 출처.
  • Access-Control-Request-Method: 실제 요청에서 사용할 메서드.
  • Access-Control-Request-Headers: 실제 요청에 포함될 추가 헤더.

프리플라이트 응답 예시

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

응답 헤더 설명

  • Access-Control-Allow-Origin: 서버가 허용한 출처.
  • Access-Control-Allow-Methods: 서버가 허용한 메서드.
  • Access-Control-Allow-Headers: 서버가 허용한 헤더.
  • Access-Control-Max-Age: 프리플라이트 응답을 캐시할 시간(초 단위).

프리플라이트 응답의 특징

  1. 응답 코드는 200번대여야 한다.
  2. 응답 바디는 비어 있는 것이 좋다.

4. CORS 에러가 발생하는 이유

주요 원인

  1. 서버 설정 미비: 백엔드에서 CORS 설정을 하지 않은 경우.
  2. 허용되지 않은 출처: 서버가 요청한 Origin을 허용하지 않았을 때.
  3. 프리플라이트 요청 실패: 복잡한 요청을 보내기 전에 사전 확인 단계에서 실패.

5. CORS 해결방법

1. 서버 설정

Express (JavaScript):

const express = require('express');
const cors = require('cors');

const app = express();
app.use(cors({ origin: 'https://mywebsite.com' })); // 특정 출처 허용

app.get('/data', (req, res) => {
  res.json({ message: 'CORS 요청 성공!' });
});

app.listen(3000, () => console.log('서버 실행 중'));

Django (Python):

  1. django-cors-headers 설치
pip install django-cors-headers
  1. settings.py 설정
INSTALLED_APPS = [
    ...,
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...,
]

CORS_ALLOWED_ORIGINS = [
    'https://mywebsite.com',
]

2. 프록시 서버 사용

개발 환경에서는 프록시 서버를 설정해 CORS 문제를 우회할 수 있다.

React (Create React App):

  1. package.json에 프록시 설정 추가:
"proxy": "https://api.example.com"

이렇게 하면 fetch('/data') 요청이 자동으로 https://api.example.com/data로 전송됨

3. 브라우저 플러그인 활용

개발 단계에서는 브라우저 확장 프로그램을 사용해 CORS를 임시로 해결할 수 있다

플러그인 사용은 개발 환경에서만 권장되며, 배포 시에는 서버 설정을 통해 해결해야 한다

  • Allow CORS: Access-Control-Allow-Origin (Chrome 확장 프로그램)

 


참고자료

https://www.youtube.com/watch?v=bW31xiNB8Nc

https://developer.mozilla.org/ko/docs/Glossary/Preflight_request

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F#cors%EB%A5%BC_%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94_%EB%B0%A9%EB%B2%95_%EC%B4%9D%EC%A0%95%EB%A6%AC_%F0%9F%99%8C

 

 

 

 

 

 

728x90
반응형