brunch

You can make anything
by writing

C.S.Lewis

by zwoo Apr 07. 2024

CORS 해결하다가 신입사원 1년 다 보낸 이야기

주니어 프론트엔드 개발자의 생각

이번 회사에 신입으로 입사한지 1년이 되어간다. 취준할 때 네트워크 공부를 열심히 했었고, 사이드프로젝트에서도 개발서버와 API 서버 간 CORS(Cross-origin resource sharing) 정책위반에 의한 에러를 수없이 겪었기 때문에 "아, 나는 이제 브라우저의 CORS 정책이 무엇인지 이해했고, 왜 중요한지, 그리고 개발중에는 어떻게 임시로 우회할 수 있는지도 다 알게 되었다" 라고 생각하고 입사를 했다. 무엇보다 이 CORS 는 프로젝트 초반에만 겪는 문제라고 생각해서, 입사 이후에는 전혀 만날 일이 없을 줄 알았다. 설령 신규 프로젝트를 맡게되더라도, 서버개발자가 알아서 해결해줄 거라고 생각했다. 그야 당연하지 않은가? 프론트엔드 입장에서는 요청한 리소스가 브라우저에 의해 막히면 딱히 할 수 있는 게 없다. (라고 생각했다)


http -> https 

한번은 신기한 태스크를 맡게 되었다. 내가 밥을 먹으면서 별 생각 없이 내뱉은 말이 발단이 되었다.


- (나) 화면만 바꿀 건데 일일이 로컬서버 빌드하기가 좀 번거로워요. 도커도 켜야 하고, 서버 빌드가 가끔 안 되기도 해요. 수정할 프론트 코드가 간단할수록 서버 빌드를 기다리는 시간이 아까워요


- (팀장님) 그럼 로컬서버를 빌드 안하도록 해봐. 


- (나, 눈 휘둥그레해짐) 로컬서버로 API를 쏘는데 빌드를 안하고 개발할 방법이 있을까요? 


- (팀장님) 있을 수도 있겠지?


나는 이것저것 찾아보고 생각해본 끝에, '타깃 서버를 배포된 서버로 해도 되나?' 라는 물음에 이르렀다. 내 머릿속에는 'http' 라는 단어는 온갖 위험에 노출된 오염물질같은 이미지라서, 감히 https 프로토콜로 배포된 서버에 통신을 요청한다는 게 금기처럼 생각되고 있었다. 하지만 생각해보면 어차피 내가 개발하는 건 내부 직원들이 사용하는 백오피스라서 외부 유저들이 사용하는 서비스보다는 부담이 덜하고, 또 라이브서버 말고 qa 서버를 사용하면 이런 저런 테스트를 해도 안전할 것 같았다. DB가 공유되는 건, 공식 QA 기간이 아니라면 크게 문제가 되지 않을 것 같기도 했다. 


그래서 나는 개발환경에서는 타깃서버 엔드포인트가 QA 서버를 바라보도록 했다. 팀장님께 말씀드렸더니, 팀장님은 아예 인풋이 있는 hidden 페이지를 하나 만들어서 빌드 이후 런타임에 직접 타깃서버를 변경할 수 있도록 하자는 아이디어를 제안주셨고, 팀장님이 만들어주신 초안 페이지를 내가 좀더 디벨롭해서 기능을 완성했다. 생각하면 생각할수록 진짜 편리할 것 같았다. 그런데 여기서 CORS 에러가 발생했고, 서버코드를 전혀 본 적이 없던 나는 main 파일을 이리저리 살펴보면서 배포버전에서도 로컬서버로부터의 요청을 허용하도록 AllowOrigin을 적절한 곳에 넣어서 CORS 정책을 우회했다. 여기서 '이래도 되나..?' 한번 더 고민이 됐는데, 팀장님이 승인해주셔서 진행했다. 잘은 모르지만, 내 생각엔 아마도 이미 회사 내부망에서만 API를 호출할 수 있도록 보안이 걸려있어서 일단은 괜찮은 것 같다.


이 사례에서는 서버코드가 C# 으로 되어있어서 낯설었던 점과, 일일이 배포를 해봐야 디버깅을 할 수 있었던 점이 어려웠었다. 그전까지 한번도 배포해본 적이 없었는데 팀장님이 알려주셔서 감사했다. 



proxy

신규 프로젝트를 맡게 되었다. 기술스택은 프론트는 vue + vite, 서버는 Nest. 처음에는 로컬서버를 띄워서 개발했고, 개발환경에서 CORS를 우회할 수 있도록 서버 쪽에서 AllowOrigin 으로 localhost를 허용하기로 했다. 이제 이쯤이야 어렵지 않았다. 하지만 전혀 일이 없을 줄 알았던 CORS 문제는 한참 후에 더 어려운 형태로 다시 발생했다. 


- (서버개발자) 프론트에서 로컬서버 일일이 띄우는 거 번거롭지 않으세요? 


- (나) 오, 맞아요. 백오피스에서도 이부분이 번거로워서 배포서버를 바라보며 개발할 수 있도록 했었습니다. 


- (서버개발자) 그럼, 이 프로젝트에서도 그렇게 할까요?


- (나) 네, 좋아요!


...그로부터 며칠 후,


- (서버개발자) 서버쪽 대응 완료되었습니다. 이제 엔드포인트를 이쪽으로 설정하시면 됩니다. 그런데 조금 전에 제가 테스트해봤는데 로그인 후 세션정보를 못 가져오네요? 쿠키가 없어서 그런 듯합니다.


- (나) 확인해보겠습니다!


브라우저 정책에 의해 쿠키가 설정되지 않는 상황


그렇게 나는 스스로 불러온 재앙에 갇히고 말았다. 


그주 주말 내내, 나는 말하는 감자가 된 것 같은 슬픈 마음으로 vite 공식문서와 proxy 개념에 대해 찾아보았고 주변 개발자 지인과 지피티를 붙잡고 이런 저런 질문들을 하며 해결책을 찾으려고 노력했다. 결론부터 간단히 말하자면, 이 프로젝트는 서버가 직접 인증을 하고 쿠키를 주는 게 아니라, OIDC방식으로 로그인을 시키기 때문에 두개의 쿠키가 필요했다. 그런데 나는 로그인을 시도하면 리다이렉트가 되고 있다는 건 대강 인식했지만, 정확히 쿠키가 어디서 어떻게 발급되는지 알지 못해서 헤맸다. 그리고, CORS 를 우회할 수 있는 방법중에 proxy를 통해 동일 출처로 인식하게 하는 방법이 있다는 것도 이번에 찾아보면서 알게 되었다.


OIDC 방식의 로그인을 하면 이렇게 제3자 서비스를 통해 로그인을 하게 된다. 로그인 성공 이후에 앞으로 API 요청시에 프론트와 백엔드서버가 주고받을 하는 쿠키는 Cookie B 이다. 쿠키를 생성할 때 중요한 건, 어느 도메인으로 대상으로 생성하는가이다. 예를 들어 localhost 도메인을 대상으로 발급한 쿠키는 localhost 에서만 유효하다. OIDC 서비스에 redirect url 을 요청할 때 프론트가 localhost임을 명시해주어야 로컬호스트 대상으로 쿠키가 발급된다. 

OIDC 로그인



session API 를 비롯한 API 요청들은 Cookie B 를 들고 이동한다. 그런데 쿠키는 민감한 보안정보이기 때문에, http 사이트에서 https 사이트로 네트워크를 전송할 때는 쿠키가 차단되고, 앞서 본  에러메시지가 나타난다.


이때 프록시서버를 활용해서 중계시키면 브라우저 정책을 우회할 수 있다. 우리는 빌드도구로 vite 를 사용하고 있는데, vite 는 config 파일을 통해 proxy 서버를 설정할 수 있다. (엄밀히 말하자면 vite 개발서버가 동시에 프록시서버 역할도 하는 것이라고 한다) 쉽게 말해서 프론트 개발서버에서는 자기 자신에게로 API 요청을 보내도록 하고, 미리 설정한 프록시 서버를 통해 그 경로로 들어온 요청을 가로채서 경로 앞에 백엔드 도메인을 붙여서 요청하는 것이다. 만약 자세하게 알고싶다vite 서버 옵션을 확인해보자. 



proxy



마치며

OSI Layer 등등, 책으로 공부했던 네트워크 지식과 실무적으로 맞닥뜨리며 필요로 하게 되는 네트워크 지식에 차이가 있는 것 같다. 아니면, 당시 책에 나오는 내용들이 이정도로 깊이 와닿지 않아 잘 흡수되지 않은 것 같기도 하다. 일하면서 모르는 게 많다는 뜻이다. 


나는 협업하기 좋은 프론트엔드 개발자가 되고 싶다. 좋은 시니어, 똑똑한 개발자, 여러가지 좋은 수식어들 가운데에서도 같이 일하고싶은 개발자라는 말이 가장 얻고 싶은 칭호이다. 그러려면 일단 네트워크나 브라우저 관련 지식을 개발에 활용하는 데에 막힘이 없어야할 것이다. 이번에 알게된 것을 절대 잊어버리지 말자. 그리고 다음 번에 프로젝트 초기 세팅을 하게 되면 여기에서 막히지 말아야겠다. 















매거진의 이전글 개발자다운 연휴 보내기
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari