[WEB] CORS(Cross-Origin Resource Sharing)
아래의 문구는 갓 웹개발을 입문했을 때 나를 아주아주아주 괴롭혔던 친구이다. 아마 웹 개발자라면 이녀석과 한바탕 싸운 기억이 한번쯤은 있을 것이다.
Access to XMLHttpRequest at 'http://localhost:3000/tokens/phone' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:5510' that is not equal to the supplied origin. |
이것은 웹 브라우저의 보안 정책인 동일 출처 정책, SOP에 의해 현재 브라우저가 다른 출처의 자원에 접근하는 것을 막아 생긴 일이다.
SOP (동일 출처 정책, Same-Origin Policy)와
CORS(교차 출처 리소스 공유, Cross-Origin Resource Sharing)
SOP는 다른 출처의 리소스 접근을 제한하는 웹 브라우저의 보안이다.
요청의 출처를 HTTP 헤더를 통해 파악하여 악의적인 접근과 올바른 접근을 파악하기 위해서 걸려 있다.
보안 상의 이유로 브라우저는 동일 출처의 리소스만을 불러오는 것을 허용하게 되어 있으며, 다른 출처의 리소스를 사용하려면 해당 출처에서 교차 출처 리소스 공유, CORS(Cross-Origin Resource Sharing) 헤더를 포함하여 응답을 반환해주어야 한다.
동일 출처 리소스?
프로토콜과, 호스트, 포트가 모두 같은 URL에서 제공하는 리소스를 말한다.
혼동하면 안되는 점은 이것은 브라우저 보안 정책으로, 기본적으로는 리소스를 제공하는 서버에서 막는 것이 아니라 리소스를 받으려는 브라우저에서 요청 후 응답 HTTP 헤더의 출처를 비교하여 막는 것이다.
하지만 외부 라이브러리 및 OpenAPI의 사용을 위해서는 요청과 리소스를 매번 동일한 출처로만 받을 수는 없다.
이 때 필요한 것이 CORS이다. 교차 출처 리소스 공유라는 말 그대로 다른 출처의 리소스라도 CORS 정책에 의해 허용이 된다면 SOAP를 위반하더라도 자원의 접근이 가능하도록 하는 정책이다.
CORS 동작 방식
CORS의 기본적인 동작 원리는 다음과 같다.
1. 클라이언트(브라우저)의 요청
클라이언트는 요청시 HTTP Request Header에 Origin에 출처(브라우저의 것)을 포함하여 전송한다.
2. 서버의 응답
서버에서 해당 요청에 대해서 응답할 때 Header에 Access-Control-Allow-Origin를 포함하여 전송한다.
3. 브라우저의 판단
Origin과 Access-Control-Allow-Origin을 비교하여 차단 여부를 결정한다.
이것은 브라우저에 한정된 이야기로 서버와 서버간의 요청과 응답에서는 CORS 이슈가 발생하지 않는다.
CORS 이슈 해결
1. 서버에서 응답 Header에 Access-Control-Allow-Origin 헤더의 값을 설정해준다.
- 헤더에 Access-Control-Allow-Origin에 해당 클라이언트의 Origin을 추가하여 전송한다.
2. 클라이언트와 서버 사이에 Proxy 서버 두기
- 서버와 서버 간에는 CORS 이슈가 발생하지 않는다는 점을 이용
- 중간에 프록시 서버를 두어 외부 API의 요청을 프록시 서버가 담당하도록 한다.
- 외주 업체나 Open API 등으로 서버 리소스를 제공받을 때 쓰기 좋은 방법
Express에서 Access-control-allow-origin 설정하기
const app = express();
app.use(cors({
origin: 'http://123.456.789:5500' //허용할 Origin
}));
cors이라는 패키지가 있다. npm이나 yarn을 통해 인스톨받은 후 다음과 같이 설정해주자
origin에 요청 허용 주체의 Origin(프로토콜-[IP-포트] or 도메인 )을 넣어주자.
const app = express();
app.use(cors({
origin: ['http://123.456.789:5500', 'https://mydomain.com'] //허용할 Origin
}));
배열로 여러개의 Origin 설정하기
const app = express();
app.use(cors({
origin: '*' //허용할 Origin
}));
모든 Origin 허용
'WEB > CS' 카테고리의 다른 글
[Web] 인증과 인가 - JWT Auth (1) | 2023.03.02 |
---|---|
[Web] 인증과 인가 - 분산 서버에서의 세션 인증 (0) | 2023.03.02 |
[Web] 인증과 인가 - 쿠키와 세션 (0) | 2023.03.02 |