CORS

아기코린이·2022년 6월 16일
0
post-thumbnail

들어가기

웹 개발을 하다 보면, 이 에러를 적어도 한 번 쯤은 겪게 될 것이다.

코드작성 하는 것만으로도 충분히 어려운데, 거기에 오류까지 뜨면 눈앞이 깜깜하다. 이번글은 CORP가 무엇인지 알아보는 글이되겠다.

SOP

CORS가 대체 뭐길래 이런 에러를 띄우는 건지 알아보기 전에, CORS가 필요하게 된 배경인 SOP에 대해서 먼저 알아보자.

SOP
SOP은 Same-Origin Policy의 줄임말로, 동일 출처 정책을 뜻한다. 이것이 무슨 말이냐면, "서버와 클라이언트의 출처(Origin)가 동일한 경우에만 리소스를 공유하겠다." 라는 뜻이다.

프로토콜, 호스트, 포트가 모두 일치하는 경우에만 동일 출처가 된다. 아래 예시를 통해 조금 더 알아보자.

  • https://www.kakao.com vs http://www.kakao.com
    두 URI는 프로토콜이 다르기 때문에 동일 출처가 아니다. ( https / http )

  • https://www.kakao.com vs https://mail.kakao.com
    ⇒ 두 URI는 호스트가 다르기 때문에 동일 출처가 아니다. ( www.kakao.com / mail.kakao.com )

  • https://www.kakao.com:443 vs https://www.kakao.com
    https 프로토콜의 기본 포트는 443이다. 따라서, 두 URI는 프로토콜, 호스트, 포트가 모두 같은 동일 출처다.

SOP는 보안상 이점 때문에 모든 브라우저에서 기본적으로 사용하고 있는 정책이다. 서버는 출처가 동일한 클라이언트에서의 요청만을 수락하여 응답해준다. 외부의 요청을 원천적으로 차단하여 데이터 유출 등의 문제가 발생할 상황을 줄여준다.

하지만, 다른 출처의 리소스를 사용하게 될 일은 너무나도 많다. 당장 로컬 환경에서 개발을 할 때에도 클라이언트는 3000번 포트를 서버는 3001번 포트를 사용하게 된다면 둘의 출처는 달라진다.

그렇다면 외부의 리소스를 받아오는 방법은 없는 것 일까?

CORS

위 물음의 대한 대답이 CORS다. CORS는 Cross-Origin Resource Sharing의 줄임말로 교차 출처 리소스 공유를 뜻한다.

CORS 설정을 통해 서버의 응답 헤더에 Access-Control-Allow-Origin을 작성하면 SOP 때문에 접근이 불가능했던 리소스에 접근 권한을 얻을 수 있다.

즉, 앞서본 에러는 CORS 때문이 아니라, SOP 때문이다. CORS는 오히려 이 에러를 해결해줄 수 있는 방안이다.

CORS 동작 방식

프리플라이트 요청 (Preflight Request)
실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처 리소스에 접근 권한이 있는지부터 확인하는 것을 프리플라이트 요청이라고 한다.

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

단순 요청 (Simple Request)
단순 요청은 특정 조건이 만족되면 프리플라이트 요청을 생략하고 요청을 보내는 것을 말한다.

조건은 다음과 같습니다.

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

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

프론트 측에서는 요청 헤더에 withCredentials : true 를 넣어줘야 한다.
서버 측에서는 응답 헤더에 Access-Control-Allow-Credentials : true 를 넣어줘야 한다.

CORS 설정 방법

Express 서버
nodejs의 Express 프레임워크를 사용해서 서버를 만드는 경우에는, cors 미들웨어를 사용해서 간단하게 CORS 설정을 해줄 수 있다.

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

//모든 도메인
app.use(cors());

//특정 도메인
const options = {
  origin: "https://kakao.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개의 댓글