Cross-Origin Resource Sharing(CORS) 에러

Cross-Origin Resource Sharing(CORS) 에러

🚧 CORS 란.

CORS (코어스) 는 Cross-Origin-Resource Sharing의 줄임말. “서로 다른 사이트끼리 데이터를 주고 받는 걸 제어하는 웹 보안 규칙”

쉽게 말해서, “다른 사이트에서는 함부로 내 데이터 보지마!” 라고 통제한다.

📣 예시

나는 지금 https://www.food-order.com 라는 사이트(프론트), 주문 정보를 https://api.food-system.com 라는 다른 주소(API 서버)에 요청.

이렇게 주소가 다르면 “다른 출처(Origin)”이라고 말한다.

그래서 서버는 반드시 브라우저에게 이렇게 허락을 해줘야 한다.

Access-Control-Allow-Origin: https://www.food-order.com

이걸 “CORS 응답 헤더” 라고 부른다.

⛔️ CORS 에러는 왜 생기는 걸까?

서버가 허락을 안해주면, 브라우저는 이렇게 차단한다.

❌ “이 서버는 너한테 응답 못해. 보안 때문에 막을거야”

✅ 해결방법

서버에게 정확한 도메인을 허용해주거나, 특정 IP로 허용해주는 설정을 해주면 된다.

## 여러개의 IP 등록 할때..

if ($remote_addr = "1.1.1.1") {
    set $cors_origin $http_origin;
}

if ($remote_addr = "2.2.2.2") {
    set $cors_origin $http_origin;
}

if ($http_origin = "허락할도메인") {
    set $cors_origin $http_origin;
}
location / {
            uwsgi_pass ;

            # 서버가 uwsgi를 쓴다면 필요할 수도..
            uwsgi_hide_header Access-Control-Allow-Origin; 
            uwsgi_hide_header Access-Control-Allow-Methods;
            uwsgi_hide_header Access-Control-Allow-Headers;
            uwsgi_hide_header Access-Control-Allow-Credentials;

            set $cors_origin "";

            if ($remote_addr = "허락할 특정IP") { # 필요없으면 이 블럭 빼면 됨.
                set $cors_origin $http_origin;
            }

            if ($http_origin = "허락할 domain") { # 필요없으면 이 블럭 빼면 됨.
                set $cors_origin $http_origin;
            }

            
            add_header 'Access-Control-Allow-Origin' "$cors_origin" always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;

            if ($request_method = OPTIONS ) {
                add_header 'Access-Control-Allow-Origin' "$cors_origin" always;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
                add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                add_header 'Access-Control-Max-Age' 3600;
                add_header 'Content-Length' 0;
                add_header 'Content-Type' text/plain;
                return 204;
            }
        }

        location /route {
            allow ip; # 특정 IP
            deny all; # deny 정책
        }

⛺️ 옵션 설명

🚀 Access-Control-Allow-Origin

어떤 웹사이트에서 API를 요청할 수 있는지 지정, 이게 없으면 브라우저 차단 당한다.

🚀 Access-Control-Allow-Methods

어떤 HTTP 요청 종류를 허용할지 지정

🚀 Access-Control-Allow-Headers

브라우저가 보낼 수 있는 요청 헤더를 허용한다. 예를 들어, 클라이언트가 JWT 토큰을 담기 위해 Auth 헤더를 쓸 때, 서버가 이걸 허용해주지 않으면 요청 자체가 막힌다.

Content-Type도 없으면 Application/json 같은 것도 막힌다.

🚀 Access-Control-Allow-Credentials

“쿠키, 인증정보도 같이 보내도 돼”를 허용

브라우저에서 withCredentials: true를 사용하는 요청이 있으면 이 설정이 필수다.

예: 로그인 상태 유지용 쿠키, 토큰 등을 브라우저가 같이 보내려면 이게 있어야 한다.

🚀 Access-Control-Max-Age

브라우저가 CORS 체크 결과를 얼마나 오래 기억할지 설정(초 단위)

브라우저는 1시간 동안은 또 다시 OPTIONS 요청을 보내지 않고, 캐시된 정보를 쓴다.

🔥 서버 부하를 줄이기 좋음

🚀 Content-Length 와 Content-Type

OPTIONS 요청의 응답 내용 설정

  • OPTIONS는 데이터를 주고받지 않기 때문에, 응답 길이는 0
  • 그냥 텍스트로 응답하겠다는 의미
  • 브라우저가 이 응답을 제대로 처리하기 위해 필요함

댓글

댓글 남기기