[Server] SOP , CORS

Ethan Jeong·2022년 8월 16일
0

SOP 란?


  • same origin policy의 줄임말로, 동일 출처 정책을 뜻합니다.
  • '같은 출처의 리소스만 공유가 가능하다' 라는 정책이고, 여기서 말하는 출처origin는 아래와 같습니다.

출처는 프로토콜, 호스트, 포트의 조합이고 이 중 하나라도 다르면 동일한 출처로 보지 않습니다.

SOP가 생긴 이유는 잠재적으로 해로울 수 있는 문서를 분리하여 공격받을 수 있는 경로를 줄여줍니다.

SOP정책이 없다고 가정하고, 만약 은행 웹 페이지에서 로그인을 하고 로그인 정보를 노리는 코드가 있는 다른 사이트에 방문을 한다면? 해커는 나의 로그인 정보에 접근할 수 있게됩니다.

이러 상황에서의 보안을 위하여 SOP는 모든 브라우저들이 기본적으로 사용하고 있는 정책입니다.

그렇다면 다른 출처의 리소스를 사용해야만 하는 경우에는 어떻게 해야 할까요? 개발중인 웹 사이트에서 네이버 지도 api를 사용하고 싶다면?

CORS 란?


이런 상황을 타계하는 방법이 바로 CORS입니다.

  • Cross-Origin Resource Sharing의 줄임말로 교차 출처 리소스 공유를 뜻합니다.

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다.

브라우저는 SOP에 의해 기본적으로 다른 출처의 리소스 공유를 막지만, CORS를 사용하면 접근 권한을 얻을 수 있게 됩니다.

CORS 동작 방식


CORS의 동작 방식에는 크게 세 가지가 있습니다.
1. 프리플라이트 요청
2. 단순 요청
3. 인증정보를 포함한 요청

프리플라이트 (preflight request)

  • 프리플라이트 요청은 실제 요청을 보내기 전에 미리 CORS 권한만 먼저 확인합니다. 실제 요청을 처음부터 통째로 보내는 것보다 리소스 측면에서 효율적이기 때문입니다.

단순 요청 (simple request)

  • 단순 요청은 특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것을 말합니다.

하지만, 조건들을 모두 만족시키기는 어려워서 일단 참고만 하는것이 좋아보인다.

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

  • 요청 헤더에 인증 정보를 담아 보내는 요청입니다. 출처가 다를 경우에는 별도의 설정을 하지 않으면 민감한 정보를 지닌 쿠키를 보낼 수 없습니다. 이 경우에는 프론트, 서버 양측 모두 CORS 설정이 필요합니다.

CORS 설정 방법


  1. 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://codestates.com");
    // 인증 정보를 포함한 요청을 받을 경우
      response.setHeader("Access-Control-Allow-Credentials", "true");
    })
  1. Express 서버
    const cors = require("cors"); // cors 미들웨어 사용
    const app = express();
    //모든 도메인
    app.use(cors());
    
    //특정 도메인
    const options = {
      origin: "https://codestates.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
효율매니아

0개의 댓글