기존에 내가 해본 프로젝트들은 프론트와 협력해서 만든 프로젝트가 아닌 오직 백엔드 엔지니어만 존재하는 프로젝트이다. 이제 회사에서 프론트 엔지니어들과 함께 프로젝트를 진행하다보니 생각지도 못한 문제를 만났다.
회사에서 자바로 시작하는 첫 프로젝트이기 때문에 처음 셋팅부터 만들어야 했다.(기존은 파이썬으로 구성됨) 셋팅하면서의 과정들은 추후 다른 글을 통해 이야기하겠다.
회사에서 해결한 문제가 여러개가 있는데 회사에 대한 이야기를 블로그로 적는 첫 개시는 CORS로 하고 싶다. 이 문제를 해결한지는 꽤 지났지만 그때 고생하고 해결해냈던 그 과정이 아직까지도 남아있다. 고생한 만큼 그냥 지나가고 싶지 않아 이렇게 블로그로 간단하게 나마 남기려고 한다.
회사에서 슬랙으로 cors 문제에 대해 이야기가 나왔다. 안타깝게도 처음 든 생각은 'CORS가 뭐지?' 였다ㅎㅎㅎㅎㅎ
CORS는 Cross-Origin Resource Sharing
의 줄임말로 교차 출처(Origin) 리소스 공유라고 해석할 수 있다. 쉽게 말해, 다른 출처(Origin) 리소스 공유라고 생각하면된다.
💡출처(Origin)는 Protocol 과 Host 그리고 Port 까지 모두 합친 URL을 의미한다. 셋 중 하나만 달라도 cors가 발생한다.
내가 CORS 문제를 해결하면서 가장 많이 봤던 문구이다.
Access to fetch at ‘https://example.com’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.
이때는 해결하기 바뻐서 CORS 문제 도대체 어떻게 해결하는거야? 라고 했는데 사실 잘못된 질문이다. 문제가 아닌 해결방법이 CORS 적용이다. CORS 적용을 하지 않으면 SOP 정책에 의해 '동일한 출처만 리소스를 공유할 수 있다'가 적용되었기 때문에 출처가 다른 것은 차단되어 위의 문구를 만날 수 있다. CORS는 '다른 출처의 리소스 공유에 대한 허용/비허용 정책'을 말한다.
정리하자면, 이번에 겪은 문제는 주소가 달라서 발생한 문제였다. 즉, frontend의 도메인 주소와 API 서버의 도메인 주소가 달라서 발생하는 것이다. 따라서 프론트 개발자분이 요청하신 대로 cors 적용이 된다면 주소가 달라서 발생한 문제를 해결할 수 있다.
spring boot에서 cors 적용하는 방법은 크게 2가지가 있다
spring boot docs에는 @CrossOrigin과 global cors configuration를 말했고, 난 global cors configuration을 선택했다. 전자는 매 controller의 메소드마다 적용해야 하는데 그러기 보다는 전역적으로 적용해야한다는 판단하에 후자의 방법을 선택했다.
위에 내용을 보고 적용을 했는데 (주소는 예시다!)
cors가 적용이 안되었다. docs에서 하라는 대로 했는데 왜????
코드를 뒤져보다가 allowedOrigins 이외에 allowedOriginPatterns가 있었고, allowedOriginPatterns가 더 flexible 하다는 문장을 보고 코드에 적용하니 이제서야 드디어! cors가 적용이 되었다.
chatgpt에게 두개의 차이점을 물어보니
라는 답이 나왔다.
생각해보니 내가 허용하려는 주소가 http://localhost:8080 이 아니라 api에 따라 http://localhost:8080/example1, http://localhost:8080/example2 이런식으로 뒤에 붙는 것이 달라지고 있었다. 따라서 정확한 주소를 요구하는 allowedOrigins를 이용하려니 안되었었고, allowedOriginPatterns를 통해 http://localhost:8080 가 포함된 모든 경로를 허용하게 하니 cors가 적용되었던 것이었다.
사실 너무나도 힘들었고 정신이 없었다. 마음이 급해서 더 해결이 안되었었다ㅠ
기존에 있는 백엔드 엔지니어는 파이썬 엔지니어고, 처음으로 자바 프로젝트로 개시하는 과정에서 자바 백엔드는 신입인 나뿐인 상황에서 프론트엔지니어 분들과 처음으로 협업을 하게 되었는데 cors를 적용하기 위해 도움 받을 수 있는 사람이 정말 아무도 없었다.(자바/스프링을 가장 잘 아는 사람이 안타깝게도 나...🥲) 그런 상황에서 api를 만들었지만, cors가 적용이 안되니 내가 만든 api를 사용할 수가 없어, 프론트 업무가 block이 걸려버려 마음적으로 너무나도 힘들었다ㅠ 해당 스프린트 안에 해결해야할 앞으로의 업무들이 쌓여있는데 나 때문에 멈춰버렸다는 부담감이 엄청 컸지만, 일단 이 상황을 해결할 사람은 나밖에 없기 때문에 내가 어떻게해서든 해결하고 싶었다. 프론트쪽에서 자체적으로 api를 만들어서 업무를 진행할 수 있다고 하지만 그 부분은 최후의 방법이고 일단 내 욕심적으로는 허용이 안되었었다. 하루 반을 온종일 매달렸더니 결국엔 해결하게 된 cors 적용! 뿌듯하기도 했고, 프론트 시니어 엔지니어분께도 결국에는 혼자서 해결해냈다고 칭찬도 들어서 그동안의 슬픔과 두려움이 잊혀지는 순간이었다. 사실 해결하고 나니 엄청 간단한 것을 끙끙 앓았다는 느낌이 있긴 하지만, 백엔드 0년차 응애🍼니까 이것도 큰거다! 라고 스스로 칭찬을 해주었다.
후에, 프론트 시니어 엔지니어분이 그 후에 말씀해주시길, '엔지니어는 결국엔 문제를 해결하는 사람이고 그것이 실력이다. 리나는 이번에 그것을 증명한 것이다'라는 큰 위로를 받았다. 한층 더 성장한 느낌이었다!
엠마는 어딧어요!