노트 #55 | CORS

HyeonWooGa·2022년 8월 11일
0

노트

목록 보기
56/74

개요

CORS 의 등장 배경과 CORS 정의, 동작 방식, 설정 방식을 학습합니다.


학습 목표

  • SOP에 대해 이해할 수 있다.
  • CORS에 대해 이해할 수 있다.
  • CORS 동작 방식에 대해 이해할 수 있다.
  • CORS 설정 방법을 이해한다.

SOP (Same-Origin Policy)

정의

  • 동일 출처 정책을 뜻합니다.
  • 같은 출처의 리소스만 공유 가능하다는 뜻입니다.

Origin (출처)

  • 프로토콜, 호스트, 포트의 조합이 모두 동일해야 합니다.

SOP 등장 배경

  • 문서를 분리함으로써 공격받을 수 있는 경로를 잠재적으로 줄여줍니다.

CORS (Cross-Origin Resource Sharing)

정의

  • 교차 출처 리소스 공유를 뜻합니다.
  • 다른 출처에게 선택한 자원에 한해 접근할 수 있는 권한을 부여하도록 브라우저에게 알려주는 체제입니다.

SOP vs CORS

  • 브라우저는 기본적으로 SOP 에 의해 다른 출처에게 리소스 공유를 막습니다.
  • 브라우저는 특별히 CORS 를 통해 접근 권한을 얻은 다른 출처에게 리소스 공유를 허용합니다.

CORS 동작 방식

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

  • 정의

    • 실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 것입니다.

  • 방식

    • 브라우저는 서버에 실제 요청을 보내기 전에 프리플라이트 요청을 보냅니다.

    • 프리플라이트 요청에 대한 응답 헤더의 Access-Control-Allow-Origin 에 요청을 보낸 출처가 돌아오면 실제 요청을 보내게 됩니다.

    • 만약 요청을 보낸 출처가 접근 권한이 없다면 브라우저에서 CORS 에러를 띄우고 실제 요청은 전달 되지 않습니다.

  • 프리플라이트 요청이 필요한 이유

    • 실제 요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적입니다.
    • CORS 이전에 만들어진 서버들은 SOP 요청만 들어오는 상황을 고려하고 만들어졌기 때문에 프리플라이트 요청 방식이 아니면 대비가 되어있지 않습니다.
      • 만약 프리플라이트가 없을시 CORS 에러는 발생하지만 DELETE, PUT 등의 요청이 들어오면 해당 요청이 처리가 됩니다.

2. 단순 요청 (Simple Request)

  • 정의
    • 특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것입니다.
    • 조건을 모두 만족시키기는 어렵습니다.

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

  • 정의
    • 요청 헤더에 인증 정보를 담아 보내는 요청입니다.
    • 프론트, 서버 양측 모두 CORS 설정이 필요합니다.

  • 방식
    • 프론트 측 요청 헤더에 withCredentials : true 를 넣어줘야 합니다.
    • 서버 측 응답 헤더에 Access-Control-Allow-Credentials : true 넣어줘야 합니다.
    • 서버 측에서 Access-Control-Allow-Origin 설정할 때, 모든 출처를 허용하는 와일드카드(*)로 설정하면 에러가 발생합니다.
      • 인증 정보를 다루는 만큼 출처를 정확하게 설정해주어야 합니다.

CORS 설정 방법

헤더의 값 설정 방법만 알면 다양한 개발 환경에서 CORS 설정 해줄 수 있습니다.

  1. Node.js 서버
  • Node.js 로 간단한 HTTP 서버를 만들 경우 다음과 같이 응답 헤더를 설정해줄 수 있습니다.

    // Node.js 서버
    
    const http = require("http");
    
    const server = http.createServer((request, response) => {
    // 모든 도메인
      response.setHeader("Access-Control-Allow-Origin", "*");
      
    // 특정 도메인
      response.setHeader("Access-Control-Allow-Origin", "https://hyeonwooga.com");
      
    // 인증 정보를 포함한 요청을 받을 경우
      response.setHeader("Access-Control-Allow-Credentials", "true");
    })
  1. Express 서버
  • Express 프레임워크를 사용해서 서버를 만드는 경우, cors 미들웨어를 사용해서 보다 더 간단하게 CORS 설정해줄 수 있습니다.
    // Express 서버
    
    const cors = require("cors");
    const app = express();
    
    // 모든 도메인
    app.use(cors());
    
    // 특정 도메인
    const options = {
      origin: "https://hyeonwooga.com",  // 접근 권한 부여하는 도메인
      credentials: true,  // 응답 헤더에 Access-Control-Allow-Credentials 추가
      optionsSuccessStatus: 200,  // 응답 상태 200으로 설정
    };
    
    app.use(cors(options));
    
    // 특정 요청
    app.get("/example/:id", cors(), function (req, res, next) {
      res.json({ msg: "example" });
    });

참조

코드스테이츠 프론트엔드 부트캠프

profile
Aim for the TOP, Developer

0개의 댓글