VUE.js + SpringBoot 환경 CORS 이슈 해결(feat.SPA 원리)
**2022-06-17 수정: vue cofig 파일이 빌드엔 포함되지 않음을 확인, vue config 파일은 로컬환경을 위한 설정파일임, 배포 후에는 사용한 web server (nignx) 에 프록시 설정을 함으로써 web server 가 프록시 서버의 역할을 하도록 해야함
문제상황
브라우저 -> localhost:8081/login 요청 -> login 페이지 응답받음 (localhost:8081은 뷰 서버)
-> 입력후 로그인 버튼 클릭 -> 로그인 버튼 이밴트 발생 -> axios를 통해 localhost:8080/login 으로 요청 (localhost:8080은 스프링 서버) -> 응답 데이터를 화면 상단에 표시
뷰와 스프링을 합쳐서 테스트 하는 도중 첫 로직인 해당 플로우에서 CORS 이슈가 발생했다.
[이전에 CORS에 대해 자세히 정리한 링크] https://onlyforus-blog.tistory.com/139
처음엔 VUE 프론트 서버 와 백엔드서버와 통신을 하는데 왜 브라우저 스팩인 CORS가 발생하는지 의아했다.
하지만 SPA의 개념을 다시 파악 해보니 내 이해가 잘못 되어있었다.
SPA
SPA를 가능하게 하는 대표적인 프레임 워크는 React, Vue, Angular 등이 있다.
(이것들을 사용한다고 해서 프론트 엔드와 백 엔드가 구분되는 것은 절대 아니지만 프론트 엔드와 백 엔드를 독립적으로 개발할 수 있다.)
클라이언트가 요청을 보내면 프론트 엔드 서버는 미리 준비해둔 HTML, CSS, JavaScript 파일들을 클라이언트에게 제공한다.
클라이언트의 브라우저는 전달받은 정적파일을 페이지에 렌더링한다.
만약 동적 데이터가 필요한 경우에는 백 엔드 서버에게 직접 API 요청을 보내서 필요한 데이터를 요청한다. (이 부분에서 CORS 이슈가 발생한다.)
그러면 그 응답 데이터를 가지고 필요한 부분만 리렌더링을 해주게 된다.
페이지 전체 갱신 없이 필요한 부분만 데이터를 리렌더링 함으로써 이전에 하나만 변해도 모든 페이지를 리랜더링 해야했던 것과 달리 더 효율적으로 개선할 수 있다.
CORS의 원인
CORS는 서버를 위한 동일 출처 정책으로 다른 출처의 자원 사용을 막는다.
브라우저는 현재 뷰를 오리진으로 하고있다.
하지만 이밴트가 발생하고 부분적으로 리렌더링이 필요해지는 경우 API 서버인 스프링에게 직접 요청을 보내게 된다.
즉, 브라우저에서 이밴트를 발생시키면 프론트 서버에서 요청을 보내고 그 프론트 서버가 백엔드게 요청을 보내서 응답을 받고 그 응답을 브라우저에게 전달시켜주는 구조가 아니라.
브라우저에서 이밴트를 발생하면 백엔드 서버에게 요청을 보내서 응답을 바로 화면에 적용하는것이다.
따라서 뷰를 오리진으로 하고있는 브라우저에서 스프링에게 응답을 받게 되니 다른 출처의 자원임을 인식하고 이슈를 터트리는것이다.
해결
https://onlyforus-blog.tistory.com/139에서 정리했듯 대표적으로 두가지 해결 방법이 있다.
직접 헤더의 Access-Control-Allow-Origin 세팅하기
CORS 정책 위반으로 인한 문제를 해결하는 가장 대표적인 방법은,
그냥 정석대로 서버에서 Access-Control-Allow-Origin
헤더에 알맞은 값을 세팅해주는 것이다.
이때 와일드카드인 *
을 사용하여 이 헤더를 세팅하게 되면 모든 출처에서 오는 요청을 받아먹겠다는 의미이므로 당장은 편할 수 있겠지만, 바꿔서 생각하면 정체도 모르는 이상한 출처에서 오는 요청까지 모두 받아먹겠다는 오픈 마인드와 다를 것 없으므로 보안적으로 심각한 이슈가 발생할 수도 있다.
그러니 가급적이면 귀찮더라도 Access-Control-Allow-Origin: https://evan.github.io
와 같이 명확한 출처를 명시해주도록 하자.
프론트 프록시 서버 설정
앞서 CORS는 브라우저
에 포함된 스펙이기 때문에 서버끼리 통신에는 작용하지 않는다.
이를 이용해 정적 컨텐츠 제공과 프록시 서버 역할을 할 웹 서버 즉, 프론트 서버를 만들고 브라우저는 해당 서버와 통신하도록 한다.
(VUE 개발이 완성되면 빌드한 후 NGINX 등 웹 서버에 올려 배포를 하게 될텐데, 이때 프록시 설정을 해주기로 했다)
(VUE CONFIG 파일에 프록시 설정은 로컬환경에서 임시 프록시 설정임으로 배포 후에는 웹 서버에 설정을 해줘야한다. 빌드시 proxy 질문 - 인프런 | 질문 & 답변 (inflearn.com) )
이렇게 하면 브라우저 입장에서는 프론트 서버와만 통신
하기때문에 동일 출처로 판단
하기때문에 CORS가 발생하지 않는다.
프론트 서버(웹 서버)는 내부적으로 백엔드 서버(WAS)와 통신
하며 API가 필요한경우 요청해서 받아오게된다.
즉, 프론트 서버와 백엔드 서버를 분리해서 브라우저의 처리를 모두 프론트서버에게 위임하고 프론트서버는 필요시 백엔드 서버에게 리소스를 요청해 받아와 브라우저에게 전달자 역할을 하도록 설계하면 CORS 발생을 방지할수있다.
두 가지 방법을 모두 시도 해봤고 이슈를 해결할 수 있었다.
Reference
[React] 프론트 엔드와 백 엔드 분리 시 동작 원리 (vs 풀 스택) (tistory.com)
[React] 프론트 엔드와 백 엔드 분리 시 동작 원리 (vs 풀 스택)
1. 일반적인 웹 어플리케이션의 동작 원리 : 풀 스택 (Full Stack) 프론트 엔드와 백 엔드가 구분되지 않는 일반적인 웹 어플리케이션의 동작 원리는 어떠할까? 파이썬 기반의 장고(Django), 자바 기반
it-eldorado.tistory.com
Spring Boot에서 CORS 적용해보기 (tistory.com)
Spring Boot에서 CORS 적용해보기
안녕하세요! 이번 포스팅에서는 CORS가 무엇인지 간단하게 알아보고, Spring Boot에서 CORS를 적용하는 방법에 대해 알아보겠습니다. 전체 코드는 Github에서 확인이 가능합니다. ✍️ 저는 만들어둔 AP
shinsunyoung.tistory.com
vue proxy 사용하기
vue cli 3.x 버전 이상에서 웹팩 개발서버를 이용해서 프록시 요청을 보내봅시다.
velog.io
인프런에서 새로운 메시지가 도착했습니다. (inflearn.com)
빌드시 proxy 질문 - 인프런 | 질문 & 답변
react나 vue를 사용할 경우 실제 배포시 proxy 설정만 해주어도 별도의 서버설정없이 통신이 가능한건가요 ? - 질문 & 답변 | 인프런...
www.inflearn.com