crossorigin
속성의 이해
crossorigin
속성은
해당 요소에 링크된
외부 출처의 리소스와 현재 웹 페이와의 상호작용을 할 수 있도록
CORS(교차 출처 리소소 공유, Cross-Origin Resource Sharing)를 설정하는 속성입니다.
예시
다음은 <script>
요소에 링크된 외부 리소스인 https://example.com/example-framework.js
을 현재 웹 페이와의 상호작용을 할 수 있도록 교차 출처 리소소 공유 체계에서 처리하도록 하는데 요청 시 인증 정보를 보내지 않도록 지정하는 예시입니다.
사용법 참고 사항
crossorigin
속성을 이해하기 위해서는 사전에 필요로 하는 지식이 있습니다.
'외부 출처의 리소스와 현재 웹 페이와의 상호작용' 이해
동일 출처 정책(Same-origin policy)
웹은 '동일 출처 정책(Same-origin policy)'이라는 정책이 있습니다.
'현재 출처'에서 로드된 문서나 스크립트와 '외부 출처'의 리소스와 상호 작용하는 방법을 제한하는 보안과 관련된 정책입니다.
브라우저는 현재 웹 페이지에 '외부 출처'의 리소스가 링크되어 있거나 삽입되어 있을 경우에 '외부 출처'의 리소스를 로드하거나 사용하는 것은 보안적인 측면을 고려하여 제한적으로 허용합니다. 이러한 보안 정책을 '동일 출처 정책(SOP, Same-origin policy)'이라고 합니다.
여기에서 '외부 출처'란 동일한 출처가 아닌 것을 말하는데, '동일 출처'의 정의를 먼저 살펴보겠습니다.
https://example.com/app1/index.html
라는 URL이 있습니다.
https://
을 '프로토콜'(또는 '스키마', 또는 '스킴')이라고 합니다.example.com
을 '호스트'(또는 '도메인')이라고 합니다./app1/index.html
을 '파일 경로'라고 합니다.
프로토콜과 도메인이 일치해야 '동일 출처'라고 합니다. 포트가 명시된 경우에는 포트도 일치해야 합니다.
파일 경로는 상관이 없습니다.
다음의 경우는 '동일 출처'입니다.
http://example.com/appplication1/index.html
http://example.com/appplication2/index.html
다음의 경우처럼 포트(:80
)가 명시된 경우에는 포트도 일치해야 '동일 출처'입니다.
http://example.com:80/appplication1/index.html
http://example.com:80/appplication2/index.html
서로 다른 프로토콜을 사용했기 때문에 다음의 경우는 '외부 출처'입니다.
http://example.com/appplication1
https://example.com/appplication2
서로 다른 호스트 이름을 사용했기 때문에 다음의 경우는 '외부 출처'입니다.
http://example.com/appplication1
https://mayappplication.example.com/appplication2
이처럼 웹은 보상안의 이유로 '동일 출처'와 '외부 출처'를 나누고
'외부 출처'의 리소스를 로드하거나 사용하는 것은 보안적인 측면을 고려하여 제한적으로 허용합니다.
동일 출처 정책(Same-origin policy)에서 '외부 출처'의 접근을 허용하는 경우
동일 출처 정책으로 무조건 '외부 출처'의 리소스를 제한하는 것은 아닙니다.
제한적으로 '외부 출처'를 허용합니다.
대표적으로 현재의 웹 페이지에 단순 삽입(embed)되는 경우입니다.
다음은 교차 출처로 삽입(embed)할 수 있는 리소스의 일부 예시입니다.
현재의 '출처' '외부 출처' 둘 다 사용하는 것을 '교차 출처'라고 합니다.
<script src="…"></script>
로 단순히 읽기 전용 스크립트 파일 삽입<link rel="stylesheet" href="…">
로 '외부 CSS 파일 연결<video>
와<audio>
로 재생하는 미디어<img>
,<picture>
로 표시되는 이미지<iframe>
으로 삽입되는 것<object>
,<embed>
로 삽입되는 외부 리소스- CSS의
@font-face
규칙으로 적용되는 글꼴(일부 브라우저에서는 동일 출처를 요구할 수 있음)
동일 출처 정책(Same-origin policy)에서 '외부 출처'의 접근을 제한하는 경우
단순히 '외부 출처'의 리소스를 삽입(embed)하는 경우가 아니라,
현재의 웹페이지가 '외부 출처'의 리소스와의 상호 작용하는 경우에는 접근을 제한합니다. 보안에 영향을 미칠 수 있기 때문입니다.
현재의 웹페이지가 '외부 출처'의 리소스와의 상호 작용하는 경우의 일부 예시입니다.
- 데이터 통신: 현재의 웹페이지가 '외부 출처'의 리소스의 데이터와 통신하는 경우 (예: AJAX 요청을 통한 데이터 가져오기)
- 쿠키 및 저장 정보 접근: '외부 출처'의 리소스가 현재 웹페이지 정보에 접근을 시도할 경우 (예: 사용자의 쿠키에 접근을 시도)
- 단순 삽입된 '외부 출처 리소스' 내의 외부 출처 리소스: 단순 삽입된 '외부 출처 리소스' 내의 외부 출처 리소스가 있을 경우 보안을 유지하기 위해 해당 접근이 제한될 수 있습니다.
- 스크립트 실행: '외부 출처' 리소스의 스크립트를 현재 웹 페이지에서 실행하려는 경우나 '외부 출처' 리소스가 현재 웹 페이지의 스크립트 API를 호출하려는 경우 (일부 특정 API는 허용될 수 있습니다.)
동일 출처 정책(Same-origin policy)으로 제한하는 '외부 출처' 리소스의 접근을 허용하는 방법
교차 출처 리소소 공유(CORS, Cross-Origin Resource Sharing)를 사용해서 교차 출처의 접근을 허용하는 것입니다.
crossorigin
속성으로
교차 출처 리소소 공유(CORS, Cross-Origin Resource Sharing) 체계를 사용해서 교차 출처의 접근을 허용하게 할 수 있습니다.
교차 출처 리소소 공유(CORS, Cross-Origin Resource Sharing)
'교차 출처 리소소 공유(CORS, Cross-Origin Resource Sharing)'는 현재의 출처에서 '외부 출처'의 리소스에 접근할 수 있는 권한을 브라우저에게 요청할 수 있게 허용하는 체계입니다.
이 체계는 크게 HTML의 crossorigin
속성을 사용해서 '교차 출처'를 허용하게 지정하는 것과,
자바스크립트나 서버 사이드에서 허용하게 할 수 있는 것으로 나눌 수 있습니다.
이 글에서는 crossorigin
속성으로 교차 출처 리소소 공유(CORS, Cross-Origin Resource Sharing)에 대해 지정하는 것을 다룹니다.
crossorigin
속성으로 교차 출처 리소소 공유 설정하기
crossorigin
속성의 값으로
교차 출처 리소소 공유 체계에서 처리하는 설정 방법을 지정할 수 있습니다.
crossorigin
속성의 값으로 교차 출처 리소소 공유 체계에서 처리하는 설정 방법을 지정합니다. 이 값은 외부 출처의 리소스를 가져올 때 교차 출처 리소소 공유 체계에서 어떤 방식으로 적용할지 여부를 지정하는 것입니다.
crossorigin
속성의 값
anonymous |
교차 출처 리소소 공유 체계 요청 시 인증 정보를 보내지 않도록 설정합니다. |
---|---|
use-credentials |
교차 출처 리소소 공유 체계 요청 시 인증 정보를 보내도록 설정합니다. (예: cookie, certificate, HTTP Basic 인증) |
crossorigin
또는 crossorigin=""
처럼 빈 값을 할당하는건 anonymous
와 동일합니다.
주의할 점
링크된 리소스가 폰트 파일일 경우에는 동일 출처라 하더라도 다양한 이유로 인해 익명 모드 CORS를 사용하여 가져와야 합니다.
일반적인 리소스와 달리, 웹 폰트는 CSS의 @font-face
규칙을 사용하여 웹 페이지에 로드됩니다. 이 삽입 과정에서 브라우저는 백그라운드에서 일부 CORS 요청을 트리거할 수 있습니다. 따라서 동일 출처의 웹 폰트 리소스를 <link>
태그에 rel="preload"
로 설정하더라도 crossorigin
속성을 anonymous
으로 사용하여 실제 폰트 로딩 간의 CORS 모드 일치를 보장하는 것이 좋습니다.
이 경우를 아래의 예제로 살펴보겠습니다.
위 예시에서는 웹폰트를 <link>
태그에 rel="preload"
로 설정했습니다. 동일 출처이지만 최종 리소스 요청을 확실히 하기 위해서 crossorigin
속성을 anonymous
으로 사용했습니다.
명세서
명세서 사양 | |
---|---|
crossorigin
|
HTML Standard #cors-settings-attributes |