다른 출처의 리소스 요청을 제한하는 2가지 정책: SOP & CORS
CORS 정책을 지키지 않고 보낸 리소스 요청에 대한 에러
Cross-Origin Resource Sharing
한 출처에서 실행 중인 웹이 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 브라우저에서 알려주는 체제. 어떤 호스트에서 자신의 콘텐츠를 불러갈 수 있는지 서버에 지정할 수 있는 방법.
예시
https://domain-a.com의 프론트 엔드 JavaScript 코드가 XMLHttpRequest를 사용하여 https://domain-b.com/data.json을 요청하는 경우
보안상의 이유로 브라우저는 스크립트에서 시작한 교차출처 HTTP 요청을 제한한다. (XMLHttpRequest와 FetchAPI는 동일 출처 정책을 따름). 자신의 출처와 동일한 리소스만 불러올 수 있으며 다른 출처의 리소스를 불러오기 위해서는 그 출처에서 올바른 CORS헤더를 포함한 응답을 반환해야 함.
예비요청없이 바로 서버에 본 요청을 보내는 것.
❗️조건
1. GET, HEAD, POST 메서드 중 하나
2. Accept, Accept-Language, Content-Language, Content-Type 헤더만 허용됨
3.Content-Type을 사용할 경우 application/x-www-form-urlencoded, multipart/form-data, text/plain 값들만 허용됨
가장 많이 마주치는 방식. 예비 요청 + 본 요청으로 나눠서 서버에 전송함.
simple requests와 달리 먼저 OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청을 전송하기에 안전한지 확인함. '응답 헤더에 유효한 Access-Control-Allow-Origin이 있는가'를 판단.
인증된 요청을 사용하는 방법. 다른 출처 간 보안을 좀 더 강화하고 싶을 때 사용함.
인증정보를 포함한 요청은 HTTP cookies와 HTTP Authentication 정보를 인식함. 브라우저는 Access-Control-Allow-Credentials: true 헤더가 없는 응답을 거부함. CORS 실행 전 요청에 대한 응답은 Access-Control-Allow-Credentials: true를 지정하여 자격 증명으로 실제 요청을 수행할 수 있음을 나타내야 함.
어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식 => 잠재적으로 해로울 수 있는 문서를 분리하여 공격받을 수 있는 경로를 줄여줌
두 URL의 프로토콜(http or https),포트(:80 or :81),호스트가 모두 같아야 동일한 출처 라고 말함
http://www.example.com:8080/test?search=coffee
|프로토콜|http://|
|호스트(Host/Hostname)|www.example.com:8080|
|서브도메인(Subdomain)|www.|
|도메인|example.com|
|경로(path)|/test|
|파라미터|search|
|파라미터 값|coffee|
URL: http://store.company.com/dir/page.html
URL | 결과 | 이유 |
---|---|---|
http://store.company.com/dir2/other.html | 성공 | 경로만 다름 |
http://store.company.com/dir/inner/another.html | 성공 | 경로만 다름 |
https://store.company.com/secure.html | 실패 | 프로토콜 다름 |
http://store.company.com:81/dir/etc.html | 실패 | 포트 다름(http://는 80이 기본값) |
http://news.company.com/dir/other.html | 실패 | 호스트 다름 |
1/ 서버에서 해결
브라우저에서 CORS 에러 발견 시 서버에게 Access-Control-Allow-Origin에 유효한 값을 포함해서 보내달라고 요청
Access-Control-Allow-Origin:* (모든 출처 허용)을 세팅하면 당장은 편하겠지만 보안 이슈 생길 수 있음
2/ 백엔드와 소통하기 어려운 상황이라면
npm install --save-dev http-proxy-middleware
//setUpProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app){
app.use(
createProxyMiddleware('/api', {
target: 'https://localhost:5000',
changeOrigin: true
})
)
};
참고
MDN: CORS(교차 출처 리소스 공유)
MDN: same-origin policy(동일 출처 정책)