NginX - Reverse Proxy 로 CORS 우회하기
서론
Web Frontend 를 개발 하다보면 필연적으로 CORS 문제를 접하게 된다.
CORS 는 Cross-Origin Resource Sharing 의 약자이며… (생략) 자세한 내용은 여기와 같이 다양한 블로그에서 참고할 수 있다.
CORS 를 해결하기 위한 가장 정석 방법은 브라우저가 응답 받은 Data (Resource) 의 출처인 Server 에서 클라이언트의 origin (Scheme + Domain + Port) 를 Allow list에 추가해주는 방법이다.
하지만, Frontend 개발자 입장에서 하염 없이 Backend 의 CORS 허용 업데이트를 기다리는 것은 종종 지치는 일이다.
만약 Frontend (개발 서버 또는 로컬 등..) 에서 직접 그리고 간단하게 CORS 를 우회하는 방법을 알고 있다면 병목을 최소화 할 수 있을 것이다.
물론 Production 에서는 정석적인 방법으로 CORS 문제를 해결하는 것이 보안에 좋다.
Frontend 에서 CORS 를 우회하는 몇가지 방법들
-
Local 에 Proxy Server 띄우기 (Server → Server 통신의 경우 CORS 문제가 발생하지 않는다.)
-
NginX 로 reverse proxy 하기 지금부터 이 방법을 사용해 CORS 를 우회하는 법을 알아볼 것이다.
NginX 란?
HTTP, Reverser Proxy, IMAP/POP PROXY server를 제공하는오픈소스 웹서버 프로그램이다.
자세한 설명은 여기에서..
Reverse Proxy 란?
proxy 에는 foward proxy 와 reverse proxy 가 있다.
-
Forward Proxy
Proxy Server (NginX) 가 Origin Server 의 바로 앞단에서 Proxy 를 담당하는 구조이다.
해당 구조에서 Client 가 NginX 로부터 받는 응답의 data 는
xxx.com
출처를 갖게 된다. -
Reverse Proxy
Proxy Server (NginX) 가 Client 의 바로 뒷단에서 Proxy 를 담당하는 구조이다.
해당 구조에서 Client 가 NginX 로부터 받는 응답의 data 는
localhost:9999
의 출처를 갖게 된다.
CORS 우회하기
NginX 없이 localhost:3000
에서 https://www.google.com/
으로 Get Request 를 보내면 아래와 같이 CORS error 가 발생한다.
(Create React App 의 default 개발 서버인 3000 port 로 예시를 들었다.)
그럼 이제 Reverse Proxy 를 통해 CORS 를 어떻게 우회하는지 알아보자
1. NginX config 생성
nginx.config
파일을 생성한다.
구조는 아래와 같다.
- 80 port 를 listen port 로 열어두고,
/dev
path 는http://localhost:3000
port 로 proxy,/google
path 는https://www.google.com/
로 proxy 해준다.
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.html;
}
location /dev {
rewrite /dev/(.*) http://localhost:3000/$1 break;
# proxy 될 url 에서는 ~~/dev 을 ~~/ 로 rewrite 해준다.
proxy_set_header Host localhost;
proxy_set_header Referer localhost;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_set_header Accept-Language $http_accept_language;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://host.docker.internal:3000;
}
location /google {
rewrite /google/(.*) /$1 break;
# proxy 될 url 에서는 ~~/google 을 ~~/ 로 rewrite 해준다.
proxy_set_header Host www.google.com;
proxy_set_header Referer https://www.google.com;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_set_header Accept-Language $http_accept_language;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://www.google.com/;
sub_filter /images/ https://www.google.com/images/;
sub_filter_once off;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
2. Docker 로 NginX container 띄우기
아래 dockerfile 로 image 를 build 하고 container 를 9090 port 로 띄운다.
FROM nginx
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
# 위에서 작성한 nginx.config 를 사용한다.
docker build -t reverse-proxy .
docker run --rm -it -p 9090:80 reverse-proxy
# localhost:9090 과 NginX container 의 80 port 를 mapping 한다.
3. 구조
지금까지의 구조를 도식화 하면 아래와 같다.
- 우리는
localhost:8080/dev
에서 React 개발 서버에 접속해 작업을 한다. localhost:8080/google
로 요청을 보내 Google server 로부터 응답을 받더라도 그 Origin 은localhost:8008
이라 Same Origin 이므로 CORS 를 우회할 수 있게 된다.
4. 결과
NginX reverse proxy 를 통해 localhost:8080/dev
에서 localhost:8080/google
로 Request 를 보내면 아래와 같이 CORS 를 우회하고 HTML text 를 응답 받을 수 있다.
(React Logo 가 깨지는 문제는 static file 인 logo svg 파일을 proxy 된 host localhost:8080
에는 존재하지 않기 때문인데.. static file 들은 기존 host localhost:3000
에서 찾도록 NginX 를 설정하는 방법을 찾아봐야겠다..)
혹시 부족한 부분이 있다면 Comment 를 통해 지적해주시면 감사드리겠습니다. 🙏
Subscribe via RSS