CORS

유아현·2023년 2월 4일
0

Server

목록 보기
1/3
post-thumbnail

📌 SOP

  • Same-Origin Policy
  • 동일 출처 정책

🔥 여기서 나오는 출처 란?

다음과 같은 URI에서 https 는 프로토콜, www.naver.com 는 호스트 앞의 주소에서는 포트가 생략 되었지만 https의 기본 포트는 443으로 https://www.naver.com:443 으로 이동하였을 때 똑같은 화면이 나오는 것을 확인해 볼 수 있다. 이처럼 프로토콜 + 호스트 + 포트까지의 조합을 출처라고 한다.

SOP은 같은 출처의 리소스끼리만 공유가 가능하다는 동일 출처 정책으로 SOP을 통해 잠재적으로 해로울 수 있는 문서를 분리해 공격받을 수 있는 경로를 줄여 준다.

하지만 우리가 일상생활에서 다른 출처의 리소스를 받게 될 일은 무수히 많다. 개발을 위해 api를 활용한다거나 정보를 받아올 일이 생긴다면 다른 출처에 접근해야 한다.

모든 브라우저는 SOP을 사용하고 있는데 어떻게 하면 다른 출처에 접근해 다른 리소스를 받아올 수가 있을까? 이 상황에서 필요한 것이 바로 CORS 다! CORS대해서 자세히 알아보자.


📌 CORS

  • Cross-Origin Resource Sharing
  • 교차 출처 리소스 공유

추가적인 HTTP 헤더를 사용해 한 출처에 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.

브라우저는 SOP을 기본적으로 사용하므로 다른 리소스의 공유가 불가능한 상태인데 CORS를 사용하면 접근 권한을 부여받는 다는 것이다!

위 사진은 SOP에 의해 접근이 불가능하여 나오는 CORS 에러이다. CORS 설정을 통해 서버 응답 헤더(HTTP 헤더)에 ‘Access-Control-Allow-Origin’을 작성하면 접근 권한을 얻을 수 있다고 나와있다. 에러는 즉 CORS 때문이 아닌 SOP 정책에 의한 에러이다. 이를 해결하기 위해서 CORS 설정을 통해 해결할 수 있다.


📌 CORS 동작 방식

  1. Preflight Request

실제로 요청을 보내기 전에 OPTIONS 메서드를 통해 사전 요청을 보내서 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 방식

  1. Simple Request

특정 조건이 만족되면 Preflight 요청을 생략하고 요청을 보내는 것

🔥 특정 조건

  • GET, HEAD, POST 요청 중 하나
  • 자동으로 설정되는 헤더 외에, Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정할 수 있다.
  • Content-Type 헤더에는 application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용
  1. Credentialed Request

요청 헤더에 인증 정보를 담아서 보내는 요청, 출처가 다를 경우에 별도의 설정을 하지 않으면 쿠키를 보낼 수 없다. (프론트, 서버 모두 CORS 설정을 해야 한다.)

  • Front : 요청 헤더에 withCredentials : true
  • Server : 응답 헤더에 Access-Control-Allow-Credentials : true

서버 측에서 Access-Control-Allow-Origin를 설정할 떄 와일드 카드 *를 넣을 시에는 모든 출처를 허용되기 때문에 에러가 발생한다. 인증 정보를 다룰 때에는 출처를 정확하게 설정해 주자.


📌 CORS 설정 방법

🌞 Access-Control-Allow-Origin

  • 응답 헤더, 응답이 지정된 출처의 요청 코드와 공유될 수 있는지 여부를 나타낸다.

🔥 Node.js로 HTTP 서버를 만들 경우

const http = require('http');

// 서버 만들기
const server = http.createServer((request, response) => {
// response Header 설정, 모든 도메인
  response.setHeader("Access-Control-Allow-Origin", "*");

// response Header 설정, 특정 도메인
  response.setHeader("Access-Control-Allow-Origin", "https://google.com");

// response Header 설정, 인증 정보를 포함한 요청을 받을 경우
  response.setHeader("Access-Control-Allow-Credentials", "true");
})

🔥 Express 프레임워크를 사용해서 서버를 만드는 경우

  • cors 미들웨어를 사용하여 CORS 설정하기
// 미들웨어 cors 불러오기
const cors = require("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" });
});

0개의 댓글