[카테고리:] AWS

  • Cross-Origin Resource Sharing(CORS) 에러

    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
    • 그냥 텍스트로 응답하겠다는 의미
    • 브라우저가 이 응답을 제대로 처리하기 위해 필요함