본문 바로가기
TIL

11. 14. 27일차 TIL CORS

by 눈 새 2024. 11. 14.

오늘은  React 두번째 과제를 마무리하고 해설영상을 통해 복습한 이후 챌린지반 과제를 통해 CORS에 대해 학습하였다.


* CORS란 

CORS(Cross-Origin Resource Sharing)는 웹 애플리케이션에서 서로 다른 출처 간의 리소스 공유를 허용하는 기술로, 웹 보안과 데이터 접근성을 조화롭게 관리하기 위해 설계되었다.

 

1. 기본 개념

동일 출처 정책 (Same-Origin Policy)

  • 동일 출처 정책은 보안 모델로, 웹 페이지가 로드된 출처와 다른 출처의 리소스에 접근할 수 없도록 제한한다. 이는 악의적인 사이트가 사용자의 정보를 탈취하는 것을 방지하기 위한 것입니다.
  • 출처는 프로토콜(예: HTTP, HTTPS), 도메인(예: example.com), 포트(예: 80, 443)로 정의됩니다.

2. CORS의 필요성

웹 애플리케이션이 API를 호출하거나 외부 리소스에 접근할 때, 서로 다른 출처 간의 데이터 공유가 필요하다. 예를 들어, 프론트엔드 애플리케이션이 백엔드 API에 접근할 때 CORS가 활용된다. 이를 통해 다음과 같은 이점을 얻을 수 있다.

  • 리소스 재사용: 여러 도메인에서 동일한 API를 사용할 수 있습니다.
  • 모듈화: 다양한 서비스와 통합하여 복잡한 애플리케이션을 구축할 수 있습니다.

3. CORS 작동 원리

CORS는 요청의 종류에 따라 단순 요청과 프리플라이트 요청으로 나뉜다.

 

1) 단순요청 (Simple Requests)

단순 요청은 아래 조건을 만족하는 경우이다.

  • HTTP 메서드가 GET, POST, HEAD 중 하나일 때.
  • 요청 헤더가 Content-Type, Accept, Accept-Language, DPR, Save-Data, Viewport-Width, Width와 같은 기본 헤더만 포함할 때.

예시코드

fetch('https://api.example.com/data', {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json'
    }
});

 

위와 같은 상황에서 서버는 다음과 같이 응답해야 한다.

Access-Control-Allow-Origin: https://yourdomain.com

 

2) 프리플라이트 요청 (Preflight Requests)

플리플라이트 요청이란 브라우저가 실제 요청을 보내기 전에 서버에게 요청의 허용 여부를 확인하는 과정으로 다음과 같은 경우에 발생한다.

  • HTTP 메서드가 OPTIONS일 때.
  • HTTP 메서드가 OPTIONS일 때.
  • 사용자 정의 헤더가 포함된 경우.

예시코드

fetch('https://api.example.com/data', {
    method: 'PUT',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token'
    },
    body: JSON.stringify({ key: 'value' })
});

 

브라우저는 먼저 OPTIONS 요청을 보내게 되며, 서버는 다음과 같은 응답을 반환해야 한다.

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://yourdomain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization

4. CORS 헤더의 상세 설명

  • Access-Control-Allow-Origin: 요청을 허용할 출처를 지정한다. *로 설정하면 모든 출처에서 접근을 허용합니다. 특정 출처를 명시하는 것이 보안상 더 안전하다.
  • Access-Control-Allow-Methods: 서버가 허용하는 HTTP 메서드 목록을 지정한다. (예 - GET, POST, PUT, DELETE)
  • Access-Control-Allow-Headers: 클라이언트가 요청에서 사용할 수 있는 사용자 정의 헤더를 명시한다. (예 - Content-Type, Authorization)
  • Access-Control-Max-Age: 프리플라이트 요청의 결과를 브라우저에서 얼마나 오래 캐시할지를 정의한다. 이 값이 설정되면, 클라이언트는 지정된 시간 동안 같은 요청에 대해 프리플라이트를 생략할 수 있다.

5. CORS와 보완

CORS 설정은 매우 중요하며, 잘못된 설정은 보완 취약점을 초래할 수 있다.

  • 출처 제어: Access-Control-Allow-Origin을 *로 설정하면 모든 출처에서의 접근을 허용하게 되므로, 특정 출처만 허용하도록 설정하는 것이 좋다.
  • 민감한 데이터: 사용자 인증 정보나 민감한 데이터가 포함된 요청에 대해 CORS를 설정할 때 주의해야 한다.
  • HTTPS 사용: 보안성을 높이기 위해 HTTPS를 사용하는 것이 권장된다. 이렇게 하면 데이터 전송 중에 도청이나 변조를 방지할 수 있다

6. CORS의 구현 예시

웹 서버에서 CORS를 설정하는 방법은 서버의 종류에 따라 다르다. 예를 들어, Node.js Express 서버에서 CORS를 설정하려면 다음과 같이 할 수 있다.

 

예시코드

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

app.use(cors({
    origin: 'https://yourdomain.com', // 허용할 출처
    methods: ['GET', 'POST', 'PUT', 'DELETE'], // 허용할 메서드
    allowedHeaders: ['Content-Type', 'Authorization'], // 허용할 헤더
}));

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

app.listen(3000, () => {
    console.log('Server running on port 3000');
});

 

✔ CORS는 웹 애플리케이션에서 서로 다른 출처 간의 안전한 리소스 공유를 가능하게 하는 필수 기술이다. 이를 통해 개발자는 모듈화된 애플리케이션을 구축할 수 있으며, 사용자 경험을 개선할 수 있다. 하지만 CORS 설정은 신중하게 다뤄야 하며, 보안상의 위험을 최소화하기 위해 적절한 구성을 유지해야 한다.


★ 27일차 소감

 

오늘은 React 두 번째 과제를 마무리한 뒤 밍글데이라는 레크레이션 이벤트가 있었다. 내일부터는 팀프로젝트 시작이다. 10시 발제 이후 팀원들과 모여 워크프레임을 작성하기로 했다. 어떤 모습의 시안이 나올지 벌써  기대가 된다!