상세 컨텐츠

본문 제목

[쀼] 아 그래서 CORS가 뭐에요 : 개념 + 설정예시

CS구멍/네트워크🕊

by :부셔져버린개발자 2025. 2. 14. 11:49

본문

(개념과 동작 원리를 정확히 몰라서) 수많은 억까를 당했고
구글링으로 Mdn 문서를 찾아 이해한 후 해결함 (역시 정식대로 가야 함)
발견했던 cors 핵심 개념을 적어보고자 한다

 

CORS

CORS는 브라우저가 자신의 출처가 아닌 다른 어떤 출처로부터 자원을 로딩하는 것을 허용하도록 서버가 허가 해주는 HTTP 헤더 기반 메커니즘이다. 

 

 

CORS가 동작하는 세가지 시나리오 

1. Simple Request

Preflight Request 요청없이 서버에 직행으로 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin 헤더를 보내주면 브라우저가 CORS 정책 위반 여부를 검사한다. 

1) 요청의 메소드는 GET, HEAD, POST 중 하나다 

2) Accept, Accept--Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width 헤더일 경우에만 적용된다

3) Content-Type 헤더가 applicaiton/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나여야 한다. 아닐 경우 예비 요청으로 동작된다 

4) 요청에 ReadableStream 객체가 사용되지 않는다 

 

브라우저 => 서버 
Origin : A 
서버 => 브라우저
Access-Control-Allow-Origin : * 

 

 

2. Preflight Request

브라우저는 서버에 예비 요청을 보내 잘 통신되는지 확인한 후 본 요청을 보낸다 

브라우저가 서버에 예비 요청을 보내는 것을 Preflight라고 부르며, 이 예비 요청의 HTTP 메소드는 OPTIONS 가 사용된다. 

 

>> Access-Control-Max-Age 헤더에 캐시될 시간을 명시하여 Preflight 요청을 캐싱하여 최적화를 시켜줄 수 있다 

 

3. Credentialed Request (자격 증명을 포함한 요청)

클라이언트에서 서버에게 자격 인증 정보(Credential)을 실어 요청할 때 사용되는 요청이다

 

same-origin : 같은 출처 간 요청에만 인증 정보를 담을 수 있다

include : 모든 요청에 인증 정보를 담을 수 있다 

omit : 모든 요청에 인증 정보를 담지 않는다 

 

Access-Control-Allow-Credentials를 true로 설정하게 되면, 

Access-Control-Allow-Origin 

Access-Control-Allow-Methods 

Access-Control-Allow-Headers 값에 * 를 사용할 수 없다 

 

 

 

[문서] CORS 개념과 접근 제어 시나리오 

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

 

교차 출처 리소스 공유 (CORS) - HTTP | MDN

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 브라우저가 자신의 출처가 아닌 다른 어떤 출처(도메인, 스킴 혹은 포트)로부터 자원을 로딩하는 것을 허용하도록 서버가 허가 해주는 HTTP

developer.mozilla.org

 

 


CORS 관련 헤더 

 

Access-Control-Allow-Origin : 서버가 허용하는 출처(origin)을 정의한다 

Access-Control-Allow-Methods : 서버가 허용하는 HTTP 메소드를 정의한다 (GET, POST, PUT 등)

Access-Control-Allow-Headers : 서버가 허용하는 요청 헤더를 정의한다 (Authorization, Content-Type)

Access-Control-Allow-Credentials : cross-origin에게 자격 증명(쿠키, 인증 헤더 등)을 포함하는 요청을 허용할지 설정한다 

 

 

Access-Control-Expose-Headers : 응답에서 사용할 수 있는 추가적인 헤더를 정의한다 

Access-Control-Max-Age : 프리플라이트 요청의 캐시 시간을 설정한다. 브라우저는 이 시간 동안 동일한 CORS 요청에 대해 프리플라이트 요청을 보내지 않는다

 

 

Access-Control-Expose-Headers 가 필요한 경우

기본적으로 CORS-safelisted 응답 헤더(Cache-Control, Content-Type, ... )만 노출된다 

 

[문서] Access-Control-Expose-Headers

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

 

Access-Control-Expose-Headers - HTTP | MDN

The HTTP Access-Control-Expose-Headers response header allows a server to indicate which response headers should be made available to scripts running in the browser in response to a cross-origin request.

developer.mozilla.org

[문서] CORS-safelisted 응답 헤더

https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header

 

CORS-safelisted response header - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

A CORS-safelisted response header (also known as "simple response header") is an HTTP header in a CORS response that it is considered safe to expose to client scripts. Only safelisted response headers are made available to web pages.

developer.mozilla.org

 

 

Access-Control-Allow-Credentials 와 Request.credentials

Access-Control-Allow-Credentials : true 가 설정되지 않으면, credentials : include가 작동하지 않는다

 

[문서] Access-Control-Allow-Credentials

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials

 

Access-Control-Allow-Credentials - HTTP | MDN

The HTTP Access-Control-Allow-Credentials response header tells browsers whether the server allows credentials to be included in cross-origin HTTP requests.

developer.mozilla.org


CORS 관련 에러

Reason: CORS header 'Access-Control-Allow-Origin' does not match 'xyz'

Access-Control-Allow-Origin 'xyz' 추가 

 

Reason: Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'

동시 설정 불가 

 

Reason: expected 'true' in CORS header 'Access-Control-Allow-Credentials'

Access-Control-Allow-Credentials true 설정

 

Reason: invalid token 'xyz' in CORS header 'Access-Control-Allow-Headers'

preflight 요청으로 Access-Control-Allow-Headers 헤더가 서버의 응답으로 제공된다. 이때, 유효하지 않은 값이 Access-Controll-Allow-Headers에 포함되면 해당 에러가 발생한다 

 


>> Preflight 요청, 와일드 카드 사용 불가 내용을 몰라 고생을 했었다 

 

Nginx 설정 예시

location / {
    if ($request_method = 'OPTIONS') { // preflight 요청 처리 
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain';
        return 204;
    }

    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
}

 

Spring Boot 설정 예시

@Configuration
@EnableWebMvc
public class WebMvcConfiguration implements WebMvcConfigurer {
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
			.allowedOriginPatterns("https://www.vvue.site", "http://localhost:3000") // Development environment
			.exposedHeaders("Authorization", "refresh-token")
			.allowCredentials(true); // true로 설정했으므로 origin, method, headers 를 * 로 설정 못함
	}
}

 

 

allowedMethods를 설정 안하면 GET, HEAD 만 허용된다 

728x90

관련글 더보기