CORS 관련하여서는 어떤 문제가 발생하여도 해결할수 있을정도로 개념이 잡혀있다고 생각했다.
하지만.. 사이드 프로젝트 운영환경에서 CORS 가 발생하였고,
해당 과정을 해결하고 어느정도의 결과를 도출할 때 까지 5일이라는 시간이 걸렸다.
구조의 아키텍트를 간단하게 그려보았다..
프론트 서버: frontend.co.kr
백엔드 서버: backend.co.kr
문제 발단
프론트: 서버에서 프론트 페이지 res.redirect를 시켜주면 안되나?
백: 음.. 그럼 res.json 에서 res.redirect 로 수정하겠다.
수정 후 아래 에러 발생....
blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
백엔드 서버에 frontend.co,kr만 cors를 적용해놓았고 nginx부터 다시 점검해봤지만 전혀 문제가 없었다.
네트워크 탭의 headers를 유심히 보는데 request header에 access-control-allow-origin이 * 로 박혀있는 것을 확인
프론트 서버를 내가 직접 띄운게 아니라 자세하게 파악이 안되어서, 여기서 부터 프론트 개발자 분께 여쭤봤다.
vercel 배포, 서버 구조 파악 시작2
vercel.json이라는 것으로 vercel 웹서버를 컨트롤 할 수 있다는 사실을 확인..!
{
"headers": [
{
"source": "/login",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "https://my-app.vercel.app" },
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
]
}
]
}
심지어 내가 직접 리엑트로 vercel까지 띄워보며 테스트를 해보았다. 눈으로 봐야 마음이 편안할 거 같아..
네트워크 request header allow control allow origin에 정상적으로 기입 되는 것을 확인!
하지만 여전히 오류가 발생.. 그래도 희망이 보였던건 오류의 내용이 바뀜
Access to XMLHttpRequest at 'https://frontend.app/' (redirected from 'https://backend/api/board/676e6094a6367') from origin 'https://frontend.app' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://frontend.app' that is not equal to the supplied origin.
Origin이 같은데 도대체 왜?
Origin이 같은데 도대체 왜? is not equal?
좀 더 자세히 이야기 하자면
redirect 302 로 요청이 제대로 호출 되고 그 뒤에 200 요청 GET (서버에서 기입한 res.redirect url) 에서 CORS 가 발생.
백엔드 요청 302는 정상처리되고 브라우저에서 같은 Origin으로 GET 요청을 하는데 이때 왜 CORS 가 발생하는가?
머리속이 온통 물음표 투성이였다. 개발 할 것들이 많은데 시간이 너무 지체된다는 느낌을 받아 포기 할려 했지만, 지금까지 해봤던 시행착오들이 너무 아쉬워 머리속을 맴돌았다.
다시 구글을 뒤지기 시작
생각보다 나와 비슷한 상황에서 나는 오류를 찾아보기 쉽지 않았다.
그러던 도중 나와 비슷한 상황의 블로그 글도 발견하였으나.. 해결하지 못했다고 하였다..(절망)
프론트와 백엔드를 분리하고 싶다...
8일 동안 블로그에 글을 못썼다. 글을 못쓴 이유는 8일 동안 뭔가 진전되었다고 할 만한 결과물이 안나왔기 때문이다. 8일 동안 삽질만 계속했다... 지금 공부하고 있는건 Node JS 를 이용한 로그인
blog.everdu.com
지금 이 내용을 다시보면 해결 과정을 조언 해드릴수 있을거 같지만, 이때는 왜 안되는지 도통 이해가 가지 않았다.
(에버듀님 덕분에 문제해결에 좀 더 가까이 갈 수 있었습니다..!)
머리를 계속 굴리던 도중
vercel 서버에서 나의 백엔드 서버간의 호출의 문제인가? proxy 설정이 필요한가?...
vercel.json의 rewrite를 통해 destination는 나의 백엔드 API 주소를 기입.
https://vercel.com/docs/edge-network/rewrites
Rewrites on Vercel
Learn how to use rewrites to send users to different URLs without modifying the visible URL.
vercel.com
결국 위의 설정을 통하여 브라우저가 판단하기에 프론트 서버 URL로 요청을 보내고 Vercel 서버가 rewrite(프록시 역할)을 통하여 백엔드와 요청을 주고 받으니, CORS 오류가 해결되었다!
진짜 삽질하던 모든 것들이 사아아악 내려가면서, 뿌듯했다.
하지만 response의 결과에 html코드가 전송되고. 실제 화면이 전환되지 않았다.
으잉?
왜 속 시원하게 화면이 전환 되지 않는가?..
자료를 찾던 도중 아래 두가지 URL이 많이 참고 되었다.
https://github.com/axios/axios/issues/396#issuecomment-395592900
302 received but browser does not redirect. · Issue #396 · axios/axios
Use-case: User clicked on the add button at quote page. Add quote request is send async (using Axios) to server. Server check and found user not logon. Server send a redirect 302 back to browser. B...
github.com
https://milooy.github.io/dev/240422-redirection/.
프론트엔드에서 302 Redirection을 처리하는 2가지 방법 - 브라우저, 자바스크립트
fetch로 쏜 요청이 302 Redirect되었을 때, 페이지 이동 없이 요청만 이동한다는 점 아셨나요?
milooy.github.io
결국.. 위의 말들을 참고하면
- API 응답이 302 redirection이라면 브라우저 방식을 사용하는걸 추천
- → 자바스크립트 방식은 다중 302 redirection시 페이지 이동이 아닌 API 콜을 시도
- → 1중 리디렉션이라면 자바스크립트 방식도 무방 (첨부한 코드 참조)
- UI 깜빡임이 덜한 자바스크립트 방식을 사용하고 싶다면 302 redirection보다 200 response 응답으로 브라우저에서 수동 리디렉션 하는 방식을 추천
로 정의할 수 있다.
따라서 fetch로 리다이렉션을 처리하기 위해서는
if (res.redirected && res.url) {
location.href = res.url
}
의 방식을 사용해야하고 수동으로 리다이렉션을 시켜줘야 한다. 돌고 돌아 결국 res.json으로 로직을 바꾸고 프론트에서 리다이렉트 처리하기로 하였다.
많은 과정들 속에서 네트워크의 통신 과정, CORS에 대한 개념, 심지어 프론트 개발자와 소통하기 위해 프론트 지식도 필요하고 결국 나중에는 백과 프론트의 경계가 크게 있지 않다라는 생각도 들었다..
혹시 저와 비슷한 고민을 하고 있거나, 문제에 대한 해결 방법을 찾고 있다면 댓글 남겨주시면 같이 고민과 조언을 해드릴수 있는 부분 말씀드리겠습니다!
감사합니다.
'Server & Infra' 카테고리의 다른 글
[CI/CD] Github Action 시작하기 - Docker Hub, Slack 연동 (0) | 2025.04.08 |
---|---|
JMeter - 부하 테스트 (feat. Cloud Run) (0) | 2024.09.19 |