CORS 에러

Sun Kang·2022년 2월 16일
0

공부

목록 보기
3/3
post-thumbnail

썰풀이

인턴 생활을 하면서 처음으로 서버와 통신하는 법을 배웠을때였다.
이때 코딩 실무를 배운다고 신나서 화장실도 안가고 에러난거 고치고 열심히 할때였다.
로그인페이지를 만드는데 지금 당장 서버를 구축할 수 없으니 회사에 테스트 서버에 구축된걸로 통신을 해보자고 하셨고
api 주소를 주신걸 받아 값을 받아오는데 여러가지 에러를 겪으며 문제를 해결하고 있었다.
get요청은 jsonp를 사용해서 우회해서 어떻게 받아왔는데 post에서 나오는 에러는 도저히 방법을 못찾았고 일주일동안 했는데 해결하지 못해
자괴감이 좀 많이 들었었다. 이후 도저히 모르겠다고 말하니 에러나는게 맞다고 하고 다음일을 시키셨다(????????)

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


MDN Web Docs에서는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다. 라고 설명하고 있다.

교차 출처 요청의 예시: https://domain-a.com의 프론트 엔드 JavaScript 코드가 XMLHttpRequest를 사용하여 https://domain-b.com/data.json을 요청하는 경우. 보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한합니다.

한마디로 도메인이 다른곳에서 서버에 요청을 하면 CORS에러를 발생시킨다.

동작원리

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

프리플라이트 요청은 예비 요청과 본 요청으로 나뉘는데 OPTIONS 메서드를 통해 도메인의 리소스에 요청이 가능한지 확인하고
가능하다면 실제 요청을 보내게된다.(Cross-origin 요청은 유저 데이터에게 영향을 줄 수 있기 때문에 Preflight 요청)

  • Preflight Request
    OPTIONS 요청과 함께 두 개의 다른 요청 헤더가 전송된다.
    Access-Control-Request-Method:는 어떤 메서드로 전송되는지 알려주고
    Access-Control-Request-Headers: 는 요청의 추가 헤더를 알려준다.

  • Preflight Response
    서버가 메서드와 헤더를 받을 수 있음을 알려준다.
    Access-Control-Allow-Origin:은 허가된 도메인을 말하고
    Access-Control-Allow-Methods:는 허가된 메서드를 알려준다
    Access-Control-Allow-Headers:는 허가된 헤더를 알려주고
    Access-Control-Max-Age:는 preflight 응답 캐시 기간이다.

2. 단순요청(Simple Request)

단순요청은 요청을 보내면서 즉시 cross origin인지 확인하는데 조건이 모두 충족해야한다

  • GET, POST, HEAD중 하나일것
  • 헤더는 Accept, Accept-Language, Content-Language, Content-Type만 허용
  • Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data, text/plain 만 허용

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

브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest 객체나 fetch API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 기본적으로 요청에 담지 않기 때문에 credentials 옵션을 변경하지 않는 이상 쿠키를 주고 받을수 없다.
옵션은 세가지가 있다

  • omit: 쿠키들을 전송하거나 받지 않는다
  • same-origin: 동일 출처라면 user credentials (cookies, basic http auth 등..)을 전송한다.
  • include: cross-origin 호출이라 할지라도 언제나 user credentials (cookies, basic http auth 등..)을 전송한다.

CORS 정책 위반 해결방법

1. Access-Control-Allow-Origin 응답 헤더 세팅

서버측 설정에서 접근 권한을 주는 헤더를 추가하여 해결해준다.

app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*"); 모든 도메인
res.header("Access-Control-Allow-Origin", "https://example.com"); 특정 도메인
});

이름만 봐도 알 수 있듯이 모든 도메인 허용은 좋지 않으므로 특정 도메인이나 특정 요청만 허용하는게 좋다.

2. 특정 미들웨어 사용

Node.js 같은 경우 미들웨어 CORS로 쉽게 문제를 해결할 수 있다

const cors = require("cors");

const options = {
origin: "http://example.com", 접근 권한을 부여하는 도메인
};

app.use(cors(options));

3. 프록시 서버 사용

기본적으로 CORS 에러는 브라우저에 관련된 정책이다. 즉 서버와 서버간에 통신에는 정책이 사용되지 않으므로
거처가는 서버를 두고 요청하는 방법이다.
남이 만든 프록시 서버를 사용하는 방법과 직접 프록시 서버를 구축하는 방법으로 나눠지며
다른 사람의 프록시 서버를 사용한다면 요청해야 하는 URL 앞에 프록시 서버 URL을 붙어서 요청하면 된다.

출처

https://xiubindev.tistory.com/115
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://ingg.dev/cors/

profile
하루에 한개씩!

0개의 댓글