웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생하는 상황은 굉장히 흔하다
CORS는 Cross-Origin Resource Sharing의 줄임말로, 한국어로 직역하면 교차 출처 리소스 공유라고 해석할 수 있다.
CORS에러가 발생하는 원인은 CORS가 동일 출처 정책을 따르고 있기 때문이다
동일 출처 정책 규칙
http://www.example.com/dir/page2.html | 성공 | 프로토콜, 호스트, 포트가 동일 |
http://www.example.com/dir2/other.html | 성공 | 프로토콜, 호스트, 포트가 동일 |
http://username:password@www.example.com/dir2/other.html | 성공 | 프로토콜, 호스트, 포트가 동일 |
http://www.example.com:81/dir/other.html | 실패 | 프로토콜, 호스트가 동일하지만 포트가 다름 |
https://www.example.com/dir/other.html | 실패 | 프로토콜이 다름 |
http://en.example.com/dir/other.html | 실패 | 호스트가 다름 |
http://example.com/dir/other.html | 실패 | 호스트가 다름 (정확한 일치 필요) |
http://v2.www.example.com/dir/other.html | 실패 | 호스트가 다름 (정확한 일치 필요) |
http://www.example.com:80/dir/other.html | 상황에 따라 | 포트 명시적. 브라우저의 구현에 따라 결과가 다를 수 있음. |
동일 출처 정책이 필요한 이유
출처가 다른 두 어플리케이션이 자유로이 소통할 수 있는 환경은 보안에 취약한 환경입니다
만일 제약이 없다면, 해커가 CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting) 등의 방법을 이용해서 우리가 만든 어플리케이션에서 해커가 심어놓은 코드가 실행하여 개인 정보를 가로챌 수 있습니다
- 사용자가 악성 사이트에 접속한다.
- 이때 해커가 몰래 심어놓은 악의적인 자바스크립트가 실행되어, 사용자가 모르는 사이에 어느 포털 사이트에 요청을 보낸다.
- 그럼 포털 사이트에서 해당 브라우저의 쿠키를 이용하여 로그인을 하거나 등 상호작용에 따른 개인 정보를 응답 값을 받은뒤, 사이트에서 해커 서버(hacker.example.com)로 재차 보낸다.
- 이외에도 사용자가 접속중인 내부망의 아이피와 포트를 가져오거나, 해커가 사용자 브라우저를 프록시처럼 악용할 수도 있다.
따라서 이러한 악의적인 경우를 방지하기 위해, SOP 정책으로 동일하지 않는 다른 출처의 스크립트가 실행되지 않도록 브라우저에서 사전에 방지하는 것이 좋습니다
CORS 허용하기
때에 따라서 다른 출처라도 허용해야 될때가 있습니다
해결하는 방법은 여러가지가 있습니다
방법1 (Access-Control-Allow-Origin)
서버에서 Access-Control-Allow-Origin 헤더안에 허용할 출처를 보내면 됩니다
서버에서 보낸 응답헤더 안에 Access-Control-Allow-Origin와
클라이언트에서 보낸 요청 헤더의 Origin과 비교하여 동일하면 다른 출처라도 접근을 허용합니다
방법2 (proxy)
webpack dev server에서 제공하는 proxy 기능을 사용하는 방법이 있습니다.
webpack dev server의 proxy를 사용하게 되면, 브라우저 API를 요청할 때 백엔드 서버에 직접적으로 요청을 하지 않고, 현재 개발서버의 주소로 우회 요청을 하게 됩니다.
그러면 웹팩 개발 서버에서 해당 요청을 받아 그대로 백엔드 서버로 전달하고, 백엔드 서버에서 응답한 내용을 다시 브라우저쪽으로 반환합니다.
CRA로 만든 리엑트 프로젝트에서는 package.json에서 "proxy" 값을 설정하여 쉽게 적용할 수 있도록 구성이 되어 있습니다.
...
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy" : "우회할 API 주소"
}
방법3 (React Proxy)
http-proxy-middleware 라이브러리를 사용하여 해결하는 방법이 있습니다
라이브러리 설치
npm install http-proxy-middleware --save
React App의 src 파일 안에서 setupProxy.js 파일을 생성하고 라이브러리 파일을 불러온 다음 아래처럼 작성하면 됩니다
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api', //proxy가 필요한 path prameter를 입력합니다.
createProxyMiddleware({
target: 'http://localhost:5000', //타겟이 되는 api url를 입력합니다.
changeOrigin: true, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분입니다.
})
);
};
'웹' 카테고리의 다른 글
기술면접 준비 (0) | 2023.02.06 |
---|---|
Lighthouse를 이용한 웹 페이지의 품질을 개선 (0) | 2022.12.05 |
웹 표준과 접근성 (0) | 2022.11.08 |
Same-Origin Policy와 CORS (0) | 2022.10.19 |
HTTP 메세지 구조란? (0) | 2022.10.19 |