blaybus와 두핸즈의 콜라보 대회로
기존에 두핸즈 구글 스프레트 시트로 관리하던 두핸즈 사원들 성과를 앱에서도 관리하고 사원들이 접근할 수 있게 하는 목적이었다.
킥오프 때 상세 기획을 알려줬고, 추가 기능은 팀에서 자율적으로 결정하라고 했다. 기존에 쓰건 구글 스프레드 시트와의 동기화 (구글 시트에서 데이터 변경하면 앱에도 적용, 앱에서 데이터 변경하면 구글 시트에도 적용되어야 함)까지 구현해야 했고 실제로 사내에서 사용될 앱이라고 했다..
(상금 170만원으로 10일동안 이정도를 원하는 걸 보고.. 많은 생각이 들었다 하하)
참가했던 이유는 해커톤을 한번도 참여해보지 않아 나도 단기간에 하나의 서비스를 만들어보고 싶었기 때문이다. pm, 디자인, 다른 개발자들이 모두 있는 팀에서 협업해보고 싶었고 함께하면서 짧은 기간에 성과를 내는 것에 로망이 있었다 (?)
10일 동안 나는 어디까지 할 수 있을지도 궁금했고 하나의 일을 도전하는데 생각만 하고 행동은 못했던 나를 반성하며 '일단 해보자'는 생각으로 뛰어든 것 같다..
로그인 서버 개발을 내가 맡게 되었는데 프론트는 로그인 개발을 제대로 해본 적이 없었다.
팀 디자이너와 pm이 초반에 개인적인 사정으로 시간을 내지 못했기에 일정이 뒤로 밀렸고 우리팀은 시간이 너무 부족했기에 jwt를 하기엔 무리가 있어보여 프론트가 조금이라도 익숙한 세션 방식으로 구현했다.
나도 rest api로 프론트에서 쿠키를 받는 것은 처음이였는데 쿠키의 samesite 옵션이 none으로 설정되어 있지 않아 cors를 정통으로 맞게 된다..
쿠키의 samesite는 Strict, Lax(기본값), None이 있는데 프론트와 서버의 도메인이 다르기 때문에 꼭 none으로 설정해야 했다. none 설정을 위해서는 http가 아닌 https에서만 설정할 수 있기 때문에 급하게 nginx로 https를 설정했다. 처음에는 애플리테이션 단에서 설정을 했었는데 먹히지 않아 nginx에서 설정했더니 됐다. proxy_cookie_flags ~.* SameSite=None Secure;
Nginx와 같은 리버스 프록시를 사용하는 경우, 클라이언트와 서버 사이에서 헤더나 쿠키를 가로채거나 수정할 수 있기 때문에 설정이 안먹혔던 것 같다.
처음으로 https를 적용해보면서 http와 https의 차이를 알게 되었고 안정적인 서버를 만들겠다던 내가 보안의식이 많이 부족했다는 생각이 들었다.
location / {
proxy_pass http://localhost:8080;
# OPTIONS 요청 처리 및 CORS 헤더 설정
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "http://localhost:3000" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Allow-Credentials "true" always;
return 204; # No Content
}
# 프록시 헤더 설정
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
cors는 이론적으로만 알고 있었는데 이번 기회로 CORS 동작 원리에 대해 알게 되었다.
브라우저가 본 요청을 보내기 이전, Preflight Request를 OPTIONS 메서드로 요청을 보내어 실제 요청이 안전한지 확인한다.
그래서 nginx 설정에서 options 메서드 요청에 필요한 헤더를 담아 204 코드로 반환했다.
짧은 기간 프론트에게 빠르게 api를 제공해야 하는 서버의 입장에서 코드 리뷰를 꼼꼼히 진행하기는 어렵기에 코드래빗을 이용했다. 나의 PR도 요약해주고 리뷰도 해주고..~ 아주 좋은 녀셕이었다. 만약 나중에 해커톤을 나가게 되면 적용하고 싶다.
이번 프로젝트에서는 백엔드 팀원과 엄청난 갈등을 겪었다. 요구사항이 많이 복잡했고 백엔드에서 할 일이 많았는데 초반에 연락도 잘 안보고 내가 하는 말에 알겠다고만 할 뿐 능동적인 태도를 볼 수 없었다. 어려운 점이 있다면 개발 방법을 바꾸던가 포기할 부분을 정하든가 해야 하는데 진전이 없었다. 그리고 매일 전체 팀원들에게 카톡 스크럼 회의를 하자고 했었는데 백엔드 팀원은 아무 말이 없었다.
PR하는 법도 알려주고 독감에 걸렸다길래 쉬운 기능은 이 팀원한테 넘겼기에 내가 할 수 있는 걸 했다고 생각했다.
초반에 진지하게 소통이 안되는 부분을 언급했으니 좋아질 거라 생각해서 열심히 개발하고 있겠거니 했지만.. PR을 봤는데 제대로 개발되지 않은 부분이 많았다.
많이 아쉬운 부분이 있지만 다음에 이런 상황이 온다면... 하루에 몇 시부터 몇 시까지 몇 시간을 쓸 예정인지, 매일 아침에 오늘 무엇을 할지, 밤에는 오늘 무엇을 했는지 말해달라고 요구해야 할 것 같다. 애초에 대회 참가 목적이 다르지 않았나 하는 생각도 들었고 미리 파악해 팀빌딩에 신중해야겠다는 깨달음도 있었다.
파이널데이 전날에는 팀원들 모두가 밤을 샜고 앱에 부족한 부분이 많았지만 pm분이 발표를 잘해주셨다..!
다른 팀 발표도 듣고 시연도 해보면서 많이 배울 수 있었다. 앱 브로셔를 만들어온 팀도 있었고 구글 시트와의 연동을 함 팀도 많았고 redis에 최근 획득 경험치를 저장하는 팀도 봤다. 난 ci/cd는 스트립트 짤 시간이 없어서 안했는데 그냥 하는 게 더 시간을 절약했을 것 같다.
블레이버스 협업 툴을 사용했어야 했는데 우리팀은 약 300시간 정도를 투자했다.
앱 마스코드 두두(여우 캐릭터)가 귀여워서 그런지 최종 5순위 안에 들었다는 연락이 왔다! UI/UX에 관심이 생겨 대회 전까지 UI/UX를 하고 있었는데 팀 디자이너 분이 디자인을 잘해주셔서 어깨 넘어 볼 수 있다는 게 좋았다.
초기 세팅에 너무 많은 시간을 들였고 이런 대회에 참가할 때는 세팅을 먼저 해놓는 게 맞는 것 같다. 나는 마지막날 기존 팀에 투입된거라 이럴 시간이 없었지만 다음에는 무조건 초기 세팅을 완료하고 시작해야겠다.
나는 모든 팀원들의 참가 이유를 좋은 경험을 하고싶어서라고만 생각했고 이미 알고 있는 기술로 빠르게 앱을 만들어야 한다고 생각했다.
근데 프론트는 새로운 기술을 써보고 싶어서 리액트를 선택하고(이것도 나중에 알았다) fcm 개발, 로그인, 리액트 배포 등 다 처음이라 찾아보면서 개발해야 했는데 나로써는 많이 답답했다.
모든 사람이 대회에 참여한 이유가 다르고 어느 정도 열심히 하고 싶은지도 다르기 때문에 다음에는 킥오프 때 개인적인 목적과 개발 실력, 투자할 수 있는 시간을 얘기하고 시작해야겠다고 생각했다.
알림 기능은 코드 리뷰를 해본 것, 남이 해놓은 코드 버그 고친 것 정도만 해봤었는데 이번에 처음부터 쌩으로 하다보니 남 코드 볼 때랑은 확실히 달랐다. 알림 전송 코드가 곳곳에 흩어져있고 게시글 등록 시 모든 사용자에게 알림을 전송해야 했기 때문에 속도가 많이 느려졌다. 역시 그냥 알고 있는거랑 직접 해보는 거랑은 다르다! 나중에 다른 프로젝트에서 알림 개발을 한다면 비동기 처리를 해보자..!!!