버킷 CORS 정책
버킷 CORS 정책 구성
CORS(Cross-Origin Resource Sharing)는 특정 도메인에서 실행되는 웹 애플리케이션이 다른 도메인의 자원에 접근할 수 있도록 하는 기능입니다. Object Storage 서비스의 버킷(Bucket)에 대한 CORS 정책을 설정하여 특정 도메인에만 응답하도록 옵션을 설정할 수 있습니다. 버킷에서 설정할 수 있는 CORS 정책은 최대 10개입니다.
Object Storage에서 버킷에 대한 CORS 정책 구성은 다음과 같습니다.
CORS 정책 설정 시, 상세 규칙을 따르지 않으면 400 Bad Request 에러가 발생할 수 있습니다.
CORS 정책 비교 순서
2개 이상의 CORS 정책을 입력한 후 요청이 들어온 경우 CORS 정책의 비교 순서는 다음과 같습니다.
- CORS 정책이 입력된 순서대로 비교를 진행
- CORS 정책 목록 중 처음 일치한 Origin에 대한 정책을 확인
- list 중 처음 일치하는 origin에 대해서 allowed_methods와 allowed_header를 확인하고 응답을 생성
CORS 정책 구성 요소
CORS 정책의 구성 요소는 다음과 같습니다.
| 항목 | 설명 |
|---|---|
| allowed_origins | 해당 버킷의 CORS를 허용할 출처를 지정함 - 예시: https://example.com |
| allowed_methods | 버킷과의 CORS를 허용할 HTTP 메서드를 지정함 - Access-Control-Allow-Methods는 성공적인 Preflight 요청에 대한 응답으로 값이 헤더에 반환됨 |
| allowed_headers | 버킷과의 CORS를 허용할 헤더를 지정함 - Access-Control-Allow-Headers는 성공적인 Preflight 요청에 대한 응답으로 값이 헤더에 반환됨 |
| expose_headers | 응답 헤더는 Access-Control-Expose-Headers 응답의 일부로 노출되는 헤더 이름을 나열함 |
| max_age_seconds | Preflight OPTIONS 요청 응답을 캐시 만료하는 시간(초) - Access-Control-Max-Age Preflight 요청에 대한 응답으로 헤더에 반환됨 |
CORS 구성 요소별 상세 규칙
CORS 정책 구성 요소별 상세 규칙을 준수해야 합니다.
allowed_origins
접근을 허용하는 origin을 의미하며, 필수 항목입니다.
- 대소문자 구분
- 최대 1개의 *(wild card) 문자 포함 가능
- 가능 (console.*.kakao.io)
- 불가능 (..kakao.io)
- origin 당 최대 입력 가능 길이: 200
- CORS 정책당 입력할 수 있는 최대 : 10
- 입력 허용 문자
- alpha-numeric
- colon (:)
- forward-slash (/)
- dot (.)
- wild card (*)
- regex : '^[a-zA-Z0-9:/.-]$' = 알파벳 대소문자, 숫자, 특수문자 (
*,:,/,.,-) 만을 허용함 - 이외 다른 문자와 혼합하여 사용할 수 없음
- CORS 구조체 당 최대 입력 개수: 10개
Details
allowed_methods
접근을 허용하는 메서드(HTTP)를 의미하며, 필수 항목입니다.- 대소문자 구분
- 대문자 입력만 정상으로 인식
- 소문자 입력 시 return 400 Bad Request 오류 출력
- 입력 허용 문자
- wild card (*)
- 이외 다른 문자와 혼합하여 사용할 수 없음
- regex: '^[A-Z]$' = 알파벳 대문자, 특수문자 (
*) 만을 허용함 - 중복된 입력값 가능
- 입력할 수 있는 값 : GET, PUT, POST, DELETE, HEAD, *(와일드 카드 입력 시, 앞 메서드 5개만 적용)
- CORS 구조체 당 최대 입력 개수 : 5개
allowed_headers
접근을 허용하는 헤더(브라우저에 기본적으로 노출됨)를 의미하며, 필수 항목입니다.
- 대소문자 구분
- 최대 1개의 *(wild card) 문자 포함 가능
- allowed_headers 당 최대 길이 = 200
- 입력 허용 문자
- alpha-numeric
- dash (-)
- wild card (*)
- 이외 다른 문자와 혼합하여 사용할 수 없음
- regex : ‘^[a-zA-Z\d-*]+$’ = 알파벳 대소문자, 숫자, 특수문자 (
-,*) 만을 허용함
- CORS 구조체 당 최대 입력 개수 : 10개
expose_headers
접근을 허용하는 헤더(브라우저에 기본적으로 노출되지 않음)를 의미하며, 필수 항목입니다.
- expose_headers 당 최대 길이 = 200
- 입력 허용 문자
- alpha-numeric
- dash (-)
- wild card (*)
- 이외 다른 문자와 혼합하여 사용할 수 없음
- regex: ^[a-zA-Z0-9-] * $ = 알파벳 대소문자, 숫자, 특수문자 (
-) 만을 허용함 - CORS 구조체 당 최대 입력 개수 : 10개
x-account-meta-*,x-container-meta-*,x-object-meta-*와 같은 헤더는*이 아닌 사용자가 설정한 정확한 메타(meta) 이름을 입력해야 함
max_age_seconds
Preflight request 결과를 캐싱하는 수명을 의미하며, 선택 항목입니다.
- 시간을 초 단위로 입력받음
- 0 이상 정수만 입력 가능
- 최대 입력은 1일 (86400)
- 미입력 시 default value(0)로 설정
HTTP Header 목록
CORS의 Request와 Response에서 사용하는 HTTP 헤더 목록은 다음과 같습니다. HTTP 헤더에 대한 자세한 설명은 다음 문서를 참고하시기 바랍니다.
- https://www.rfc-editor.org/rfc/rfc9110.html
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept
- https://docs.openstack.org/api-ref/object-store/
| 항목 | 설명 |
|---|---|
| Accept | MIME 유형으로, 클라이언트가 이해할 수 있는 콘텐츠 유형이 무엇인지를 알려주는 요청 HTTP 헤더 - 콘텐츠 협상을 이용하여 서버는 제안 중 하나를 선택해 사용하며, Content-Type 응답 헤더로 클라이언트에게 선택된 유형을 알려줌 - 브라우저는 요청이 이루어진 컨텍스트에 따라 해당 헤더에 대해 적당한 값들을 설정하며, CSS 스타일시트를 불러올 경우 이미지나 비디오, 스크립트를 불러올 때와 다른 값이 요청에 대해 설정됨 |
| Accept-Ranges | 부분 요청의 지원을 알리기 위해 서버에 의해 사용되는 표식인 응답 HTTP 헤더 - 이 필드의 값은 범위를 정의하기 위해 사용될 수 있는 단위 |
| Content-Disposition | 일반적인 HTTP 응답에서 콘텐츠가 브라우저에 inline 되어야 하는 웹페이지나 웹페이지의 일부인지, attachment로써 다운로드되거나 로컬에 저장될 용도로 쓰이는지 알려주는 헤더 |
| Content-Encoding | 미디어 유형을 압축하기 위해 사용되는 개체 헤더 - 해당 헤더 존재 시 그 값은 개체 본문에 어떠한 추가 콘텐츠 인코딩이 적용될지를 나타냄 또한 Content-Type 헤더에 의해 참조되는 미디어 유형을 얻도록 디코드하는 방법을 클라이언트에게 알려줌 |
| Content-Length | 수신자에게 보내지는 개체 헤더 - 개체 본문의 크기: 바이트 단위 |
| Content-Range | 전체 바디 메시지에 속한 부분 메시지의 위치를 알리는 응답 헤더 |
| Content-Type | 리소스의 media type을 나타내기 위해 사용되는 개체 헤더 |
| ETag | 특정 버전의 리소스를 식별하는 식별자인 응답 헤더 - 웹 서버가 내용을 확인하고 변하지 않았으면 웹 서버로 full 요청을 보내지 않기 때문에 효율적인 캐시와 대역폭 절약 가능 - 내용이 변경된 경우 mid-air collisions(리소스 간의 동시다발적 수정 및 덮어쓰기 현상)를 막는 데 유용하게 사용됨 |
| Expect | 요청을 적절하게 처리하기 위해 서버가 반환할 기댓값을 나타내는 요청 헤더 |
| Host | 사용자 또는 참조 리소스가 제공한 원래 URI에서 얻은 인터넷 호스트 및 요청 중인 리소스의 포트 번호를 지정하는 요청 헤더 필드 |
| Last-Modified | HTTP 헤더에 서버가 아는 가장 마지막 수정된 날짜와 시각을 담은 응답 |
| Origin | fetch가 시작되는 위치인 헤더 - 경로 정보는 포함하지 않고 서버 이름만 포함 - POST requests에 포함되는 것처럼, CORS requests와 함께 전송 - Referer 헤더와 비슷하지만, origin 헤더는 전체 경로를 공개하지 않음 |
| Range | 서버에게 문서의 일부분만 돌려주어야 한다는 것을 알려주는 HTTP 요청 헤더 - Range 헤더를 통해 여러 부분을 한 번에 요청할 수 있으며, 서버는 해당 범위에 대해 문서의 여러 부분을 돌려보냄 - 서버가 돌려보낼 경우, 206 Partial Content를 응답으로 사용해야 함 - 범위가 유효하지 않을 경우 서버는 416 Range Not Satisfiable 에러를 보냄 - 또한 서버는 Range 헤더를 무시하고 200 상태 코드와 함께 전체 문서를 돌려줄 수 있음 |
| Referer | 현재요청을 보낸 페이지의 절대 혹은 부분 주소를 포함하는 요청 헤더 - 링크를 타고 들어온 경우, 해당 링크를 포함하고 있는 페이지의 주소가 헤더에 포함됨 - 다른 도메인에 리소스 요청을 보내는 경우, 해당 리소스를 사용하는 페이지의 주소가 헤더에 포함됨 - Referer 헤더는 방문자의 출발지와 경로 및 방문 중인 페이지 등을 인식하고, 해당 데이터는 분석/로깅/캐싱 최적화에 사용 가능 |
| Transfer-Encoding | 사용자에게 entity를 안전하게 전송하기 위해 사용하는 인코딩 형식을 지정하는 헤더 |
| X-Account-Meta-* | account의 meta-data - 요청 시, account에 meta-data를 저장하는 데 사용됨 - 응답 시, account가 가지고 있는 meta-data 정보를 나타내는 데 사용됨 |
| X-Auth-Token | 인증 토큰 |
| X-Container-Bytes-Used | 사용된 총 바이트 수 |
| X-Container-Meta-* | Container의 meta-data - 요청 시, Container에 meta-data를 저장하는 데 사용됨 - 응답 시, Container가 가지고 있는 meta-data 정보를 나타내는 데 사용됨 |
| X-Container-Object-Count | 개체 수 |
| X-Object-Manifest | 동적 대형 object의 manifest - 값은 양식 컨테이너/접두사에 있는 segment 객체의 컨테이너 및 개체 이름 접두사 |
| X-Object-Meta-* | object의 meta-data - 요청 시, object에 meta-data를 저장하는 데 사용됨 - 응답 시, object가 가지고 있는 meta-data 정보를 나타냄 |
| X-Openstack-Request-Id | 이 요청에 대한 고유한 트랜잭션 ID - 문제를 보고하는 경우 서비스 제공 업체에 이 값이 필요할 수 있음 (X-Trans-Id와 동일) |
| X-Static-Large-Object | 이 객체가 정적 대형 object의 manifest인 경우 true로 설정함(응답 헤더) |
| X-Subject-Token | Authentication 성공 시 전달되는 token - 요청을 보낼 때 X-Auth-Token header에 세팅하여 Auth 정보를 전달 |
| X-Timestamp | Account, Container 또는 Object가 처음 현재 버전으로 생성된 날짜 및 시간 - 형식: UNIX Epoch Timestamp - 예시: ‘1440619048’은 ‘2015년 8월 26일 19:57:28 GMT’와 동일 |
| X-Trans-Id | 이 요청에 대한 고유한 트랜잭션 ID - 문제를 보고하는 경우, 서비스 공급자에게 이 값이 필요할 수 있음 |
| X-Trans-Id-Extra | 추가 트랜잭션 정보 - X-Trans-Id-Extra 요청 헤더를 사용해 대규모 개체 업로드 및 기타 개체 스토리지 트랜잭션에서 발생할 수 있는 오류를 디버깅하는 데 도움이 되는 추가 정보를 포함할 수 있음- 서버는 생성된 X-Trans-Id 응답 헤더의 트랜잭션 ID 값에 X-Trans-Id-Extra 요청 헤더 값의 앞 32자를 추가- X-Trans-Id-Extra 요청 헤더에 추가 트랜잭션 정보를 포함하기 전 UTF-8 인코딩 후 URL 인코딩을 수행해야 함 (예시: 이미지와 같은 큰 개체를 업로드할 경우, 추가 트랜잭션 정보를 포함할 수 있음) - 각 세그먼트와 매니페스트를 업로드할 때 X-Trans-Id-Extra 요청 헤더에 동일한 값을 포함함- 오류가 발생하면 대규모 개체 업로드와 관련된 모든 요청을 개체 스토리지 로그에서 찾을 수 있음 또한 X-Trans-Id-Extra 문자열을 사용하여 작업자가 응답을 수신하지 못하는 요청을 디버그할 수 있음- 운영자는 로그에서 추가 정보를 검색할 수 있음 |
버킷 CORS 정책 설정
CORS(Cross-Origin Resource Sharing)는 특정 도메인에서 실행되는 웹 애플리케이션이 다른 도메인의 자원에 접근할 수 있도록 하는 기능입니다.
Object Storage 서비스의 버킷(Bucket)에 대한 CORS 정책을 설정하여 특정 도메인에만 응답하도록 옵션을 설정할 수 있습니다. 단, 스토리지 관리자 역할이 부여된 사용자만 개별 버킷의 CORS 정책을 설정할 수 있습니다. 기본 CORS 정책의 Origin은 외부 도메인으로부터의 접근을 허용하지 않습니다.
Object Storage에서 버킷에 대한 CORS 정책을 설정하는 방법은 다음과 같습니다.
신규 CORS 정책 설정
신규 CORS 정책을 설정할 수 있습니다.
스토리지 관리자 역할이 부여된 사용자만 개별 버킷의 CORS 정책을 설정할 수 있습니다.
- 카카오클라우드 콘솔 > Storage > Object Storage 메뉴로 이동합니다.
- 일반 버킷 메뉴에서 정책을 설정할 버킷을 선택합니다.
- 권한 > CORS 항목에서 [설정] 버튼을 클릭합니다.
- CORS 정책은 직접 작성, 템플릿 불러오기, 기존 정책 불러오기 방식으로 설정할 수 있습니다.
- 직접 작성
- 템플릿 불러오기
- 기존 정책 불러오기
사용자가 CORS 정책을 직접 입력할 수 있습니다.
템플릿을 불러올 수 있습니다. JSON Editor에 기본 코드가 자동으로 입력됩니다.
하단의 기본 코드를 변경하여 정책을 입력합니다. 해당 코드를 그대로 사용할 경우, 사용자가 원하는 CORS 정책과 다르게 적용될 수 있습니다.
{
"cors": [
{
"allowed_origins": [
"http://example.com",
"http://example.com:8080",
"https://example.com",
"http://*.example.com"
],
"allowed_methods": [
"GET",
"HEAD"
],
"allowed_headers": [
"X-Auth-Token"
],
"expose_headers": [
"Access-Control-Allow-Origin"
],
"max_age_seconds": 0
}
]
}
다른 버킷에서 사용하고 있는 CORS 정책을 불러올 수 있습니다. JSON Editor에 다른 버킷에서 사용하는 정책이 자동으로 입력됩니다.
단, 다른 버킷의 CORS 정책을 조회하려면 storage.buckets.getiampolicy 권한이 필요합니다.
버킷 CORS 정책 구성 예시
CORS 정책 구성은 JSON 형식이어야 하고, 최대 10개까지 설정할 수 있습니다. 엔드포인트를 사용하여 웹사이트에 액세스하는 대신, “example1.com”과 같은 자체 도메인을 사용하여 콘텐츠를 제공할 수 있습니다. 정책 구성에 대한 자세한 설명은 버킷 CORS 정책 구성을 참고하시기 바랍니다.
CORS 정책 구성 예시에는 다음과 같이 CORS 정책 규칙 2개가 적용되어 있습니다.
| 규칙 | 설명 |
|---|---|
| 규칙 1 | - https://example.com, http://*.example.com Origin에서 cross-origin GET, HEAD, PUT 요청을 허용- Access-Control-Request-Headers 헤더를 통해 Preflight OPTIONS 요청의 X-Auth-Token만 허용- Preflight OPTIONS 요청에 대한 응답으로 요청된 헤더를 반환 |
| 규칙 2 | 모든 Origin에서 cross-origin POST 요청을 허용 - *(wildcard)는 모든 Origin을 의미 |
{
"cors": [
{
"allowed_origins": [
"https://example.com",
"http://*.example.com"
],
"allowed_methods": [
"GET",
"HEAD",
"PUT"
],
"allowed_headers": [
"X-Auth-Token"
],
"expose_headers": [
"Access-Control-Allow-Origin"
],
"max_age_seconds": 5
},
{
"allowed_origins": [
"*"
],
"allowed_methods": [
"POST"
],
"allowed_headers": [ ],
"expose_headers": [ ]
}
]
}