- [etc] CORS 이해하기 (Feat. *에서 탈출하기)2024년 01월 21일 03시 25분 24초에 업로드 된 글입니다.작성자: @kimyu0218
CORS 에러에 부딪히면 항상 origin에다 * 넣어서 해결했는데 드디어 CORS에 대해 공부해보기로 결심했다.
CORS
CORS란?
CORS는 Cross-Origin* Resource Sharing의 약자다. Resource Sharing이 자원 공유인 건 알겠는데 Cross Origin은 뭘까? 크로스 오리진은 서로 다른 출처를 의미한다. 즉, CORS는 서로 다른 출처 간 자원 공유다.
*origin : 자원에 접근하는 출처 (프로토콜 + 호스트 + 포트)
SOP: Same-Origin Policy
😈 origin에다 *를 넣으면 안되는 이유
CORS 요청은 보안상의 이유로 Same-Origin Policy에 의해 제한된다. Same-Origin Policy는 다른 출처에서의 접근을 막아 자원을 보호한다. 즉, CSRF 공격을 막을 수 있는 보안 정책이다.
어떻게 CSRF 공격으로부터 방어할 수 있는지 여기에 아주 잘 정리되어있다. (CSRF 외에도 CORS에 대해 쉽게 설명되어 있으니 다 읽어보는 것 추천한다!!)CORS로 Same-Origin Policy 우회하기
하지만 종종 다른 출처의 자원에 접근해야 하는 상황이 생긴다. 프론트엔드와 백엔드 주소가 다른 경우, 프론트엔드에서 백엔드의 자원을 조회하기 위해서는 SOP를 우회해야 한다.
어떻게 SOP를 우회할 수 있을까? 결론부터 말하자면 백엔드에서 `Access-Control-Allow-Origin` 헤더에 접근을 허용할 출처를 설정해줘야 한다.
CORS의 동작과정
서버에서 CORS 설정을 해줘야 하는 이유를 CORS 동작과정과 함께 알아보자.
클라이언트에서 HTTP 요청을 보낼 때, 헤더에 `Origin`을 담아 보낸다.
서버는 헤더에 `Access-Control-Origin`을 담아 요청에 대한 응답을 전송한다. (그림을 잘 보면 아직 클라이언트에게 완전히 전달된 것이 아니다!)
브라우저에서 응답을 받으면, 요청의 `Origin`과 응답의 `Access-Control-Allow-Origin`을 비교하여 차단 여부를 결정한다. 두 주소가 서로 일치하지 않는다면 CORS 에러가 발생한다.
nest 프레임워크에서 CORS 설정하기
프레임워크마다 CORS 설정방법이 다르므로 nest 프레임워크만 다룰 것이다.
const app: INestApplication = await NestFactory.create(AppModule); // 서버에서 설정하는 CORS 설정은 Access-Control-Allow-* app.enableCors({ // Access-Control-Allow-Origin origin: process.env.CORS_ALLOW_DOMAIN, // Access-Control-Allow-Methods methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // Access-Control-Allow-Credentials credentials: true, // Access-Control-Allow-Headers allowedHeaders: ['Authorization', 'Content-type'], });
`origin`에 접근을 허용할 오리진 목록들을 작성하고, `methods`에 허용할 HTTP 메서드를 정의한다. `credentials`은 자격증명을 의미하는데, true로 설정하여 쿠키, HTTP 인증정보 등을 받을 수 있도록 설정했다.
`allowedHeader`는 말 그대로 허용할 HTTP 헤더로, 클라이언트가 요청에 담아 보내는 헤더 정보를 제한한다. 나는 `Authorization`과 `Content-Type`을 받을 수 있도록 설정했다.
참고자료
'backend' 카테고리의 다른 글
[etc] Spring REST Docs와 Swagger UI를 사용한 API 문서화 (0) 2025.01.17 [etc] access token & refresh token & JWT (0) 2024.09.22 [etc] passport를 이용하여 인증/인가 구현하기 (with nest) (0) 2024.01.18 [etc] graceful shutdown으로 사용자 경험 저하 방지하기 (with docker & nest) (0) 2024.01.15 [etc] winston과 sentry로 서버가 터지는 이유 분석하기 (1) 2024.01.13 다음글이 없습니다.이전글이 없습니다.댓글