농구를 할 장소와 함께 할 친구를 찾을 수 있는 플랫폼
개발 기간: 24/01/11 ~ 24/2/22(프로젝트 발표, 구름 수료) 이후 유지보수 중
프론트엔드 3명, 백엔드 4명으로 구성되어 작업한 프로젝트입니다.
소개글 작성
-
자체 회원가입
이메일 인증을 통해 인증코드를 받는 방식으로 회원가입이 진행됩니다. 받은 인증코드를 정확하게 입력한 후, 닉네임과 비밀번호를 설정하면 회원가입이 완료됩니다.
-
소셜 회원가입
Google, Kakao, Naver 중 하나를 통해 로그인을 시도하실 경우, 최초 로그인 시 해당 계정의 닉네임, 이메일, 프로필 이미지 정보를 사용하여 자동 회원가입이 진행됩니다.
-
마이 프로필 보기
사용자는 자신의 프로필 이미지, 닉네임, 자기소개, 포지션 등의 정보를 자유롭게 수정할 수 있습니다.
-
유저 레벨 시스템
사용자의 팀 매칭 활동, 게시글 작성, 출석, 제보 등의 활동 내역을 기반으로 레벨과 포인트를 산정합니다. 이를 통해 사용자의 활동 수준과 획득한 포인트를 확인할 수 있습니다.
-
로그인
로그인한 유저에게 헤더를 통해 accessToken 및 쿠키를 통한 RefreshToken이 발급됩니다. 각각 유효기간은 1시간과 7일로 설정하였습니다.
-
로그아웃
로그아웃 시 DB에 기록된 유저의 RefreshToken에 관한 정보를 삭제 하고 유저의 쿠키 정보를 삭제합니다
-
상대방 프로필 표시
상대방 유저의 아바타를 누르면 개인정보(이메일, 소셜타입)를 제외한 프로필 정보를 보여줍니다.
-
회원 탈퇴
현재 유저의 게시물 및 채팅 기록은 살려두고 유저는 soft Delete 처리가 됩니다
default.mp4
-
상대팀 찾기 새 모집글 작성
제목, 팀명, 장소, 날짜와 시간, 규모, 원하는 실력대를 필수 입력 필드로 하고, 필드 값을 넣어 '모집 완료' 버튼을 누르면 새 모집글이 생성됩니다.
주소 선택시 카카오 지도 API를 활용하여 검색한 곳 또는 마우스 클릭으로 표시한 지점에 마커를 찍어주고, 확인 버튼을 눌렀을 때 해당 마커가 있는 곳의 주소가 주소 입력필드로 넘어가게 됩니다.
default.mp4
-
상대팀 찾기 모집글 지원하기
유저가 해당 모집글의 작성자와 다른 사람일 경우 모집글 상세페이지 하단에 '지원하기' 버튼이 표시되고, 팀명과 실력 필드 값을 넣어 '지원하기' 버튼을 누르면 해당 모집글의 지원자로 등록됩니다.
본인이 지원한 리스트는 '취소' 버튼을 통해 취소할 수 있습니다.
default.mp4
-
상대팀 찾기 모집글 지원자 수락 및 모집완료
유저가 해당 모집글의 작성자와 동일한 경우 모집글 상세페이지 하단에는 '모집 완료' 버튼과 '수정' 버튼이 표시되고, 대기중인 지원자 리스트에는 '수락'과 '거절' 버튼이 표시됩니다.
'수락' 버튼을 눌러 지원자의 신청을 수락할 수 있고, '모집 완료' 버튼을 통해 모집중인 글을 마감할 수 있습니다.
'모집 완료' 버튼을 누르면 해당 모집글은 모집 완료 상태로 변경되고, ACCEPTED된 지원자와 팀채팅(MM)이 생성됩니다.
default.mp4
-
메이트 찾기 새 모집글 작성
제목, 장소, 날짜와 시간, 포지션 별 인원 수, 원하는 실력대를 필수 입력 필드로 하고, 필드 값을 넣어 '모집 완료' 버튼을 누르면 새 모집글이 생성됩니다.
포지션 별 인원 수의 경우 각각의 모집 인원을 다 더한 값이 0인 경우에 예외처리를 해주어서 어떤 포지션이든 1명 이상 모집해야 글을 작성할 수 있도록 했습니다.
주소 선택시 카카오 지도 API를 활용하여 검색한 곳 또는 마우스 클릭으로 표시한 지점에 마커를 찍어주고, 확인 버튼을 눌렀을 때 해당 마커가 있는 곳의 주소가 주소 입력필드로 넘어가게 됩니다.
default.mp4
-
메이트 찾기 모집글 지원하기
유저가 해당 모집글의 작성자와 다른 사람일 경우 모집글 상세페이지 하단에 '지원하기' 버튼이 표시되고, 포지션과 실력 필드 값을 넣어 '지원하기' 버튼을 누르면 해당 모집글의 지원자로 등록됩니다.
본인이 지원한 리스트는 '취소' 버튼을 통해 취소할 수 있습니다.
default.mp4
-
메이트 찾기 모집글 지원자 수락 및 모집완료
유저가 해당 모집글의 작성자와 동일한 경우 모집글 상세페이지 하단에는 '모집 완료' 버튼과 '수정' 버튼이 표시되고, 대기중인 지원자 리스트에는 '수락'과 '거절' 버튼이 표시됩니다.
'수락' 버튼을 눌러 지원자의 신청을 수락할 수 있고, '모집 완료' 버튼을 통해 모집중인 글을 마감할 수 있습니다.
'모집 완료' 버튼을 누르면 해당 모집글은 모집 완료 상태로 변경되고, ACCEPTED된 지원자들과 메이트 채팅(TM)이 생성됩니다.
인증된 유저 끼리 실시간으로 채팅을 이용할 수 있습니다.
채팅방 타입은 1:1 채팅방 / 농구장 채팅방 / 같이하기 채팅방 / 팀 매칭 채팅방 이렇게 4가지 종류가 있으며,
각 타입에 따라 채팅방 이름이 결정됩니다.
채팅방 첫 입장시 입장안내 메시지,퇴장시에는 퇴장안내 메시지를 채팅방에 보여줍니다.
유저가 좌측 상단에있는 나가기 버튼을 누르면 다른 페이지로 이동을 합니다.(완전한 퇴장 x)
→ 유저가 채팅방에서 마지막으로 본 메시지를 기록하고, 재입장시에는 그 이후의 메시지만 보여줍니다.
또한 채팅방에서 과거 메세지를 조회하고 싶다면 more 버튼을 눌러서 과거 메세지 내역을 조회할 수 있습니다.
1:1 채팅방
1:1 채팅방은 채팅방을 생성할 유저 프로필 카드에서 또는 팀 매칭 완료후 팀 대표자 간 채팅방 생성이 가능합니다.
단체채팅방
단체 채팅방은 농구장 지도, 메이트 매칭에서 생성 가능합니다.
채팅 리스트에서는 유저가 참여한 채팅방 목록을 조회할 수 있습니다.
채팅방 최신 메세지, 채팅방 제목, 채팅방 타입(DM/BM/MM/TM) 을 함께 확인할 수 있습니다.
채팅 방 타입에 따라서 정해진 이름과 dm일 경우는 유저의 프로필이 채팅룸의 이미지가 됩니다.
타입별로 구분하여 명시해줍니다.
문제 발생과 해결 방법
-
소셜로그인 시 닉네임 중복 해결하기
기존 소셜에서 제공하는 닉네임을 사용하여 그대로 적용해주기로 요구사항을 정리했습니다. 구현하기에 앞서 아래와 같은 문제를 정의하였습니다.
문제원인
- 소셜 닉네임과 저희 서비스와의 동일한 닉네임이 존재하는 경우
- 소셜 닉네임의 길이가 13자를 초과하는 경우
해결방법
NicknameService라는 클래스를 만들어서 기존 소셜 닉네임의 길이 검증 ⇒ 중복 여부 판별을 하였습니다.
- 중복이 되었을 경우 “익명” + Random숫자(최대 11자)를 생성해서 익명닉네임을 부여하는 방법으로 유저에게 최대한 기존 소셜 닉네임을 사용할 수 있도록 편의성을 제공해주었습니다.
보안문제점 : 클라이언트에서 항상 필요로 하는 엑세스 토큰, 액세스 토큰을 재발급하기위한 리프레쉬 토큰을 어떻게 저장할지가 가장 어려웠습니다.
-
엑세스 토큰은 헤더에, 리프레쉬 토큰은 쿠키를 통해 클라이언트에 넘겨주기!
결정 방법 : 엑세스 토큰의 경우 클라이언트에서 메모리에 저장하여 XSS 공격을 방지하기로 하였고, 리프레쉬 토큰은 HttpOnly Secure 쿠키로 설정하였습니다.
결정 이유 :
-
엑세스 토큰의 경우 메모리에 저장하기 때문에 탈취 시 피해를 최소화 하기위하여 유효시간을 짧게 1시간으로 잡았습니다.
-
리프레쉬 토큰의 경우 클라이언트에서 별도의 관리를 할 필요가 없으므로 쿠키에 저장하여 HttpOnly Secure 방법으로 XSS 공격 방지 및 SameSite를 Lax로 설정하여서 CSRF 공격을 방지하도록 설정하였습니다.
-
헤더 vs 쿠키(장점) 왜 쿠키인지
헤더로 주면 클라이언트 스크립트로 추출해서 저장되는데 ← XSS(Cross-Site Scripting) 공격 가능해서 쿠키를 선택하게 되었다. 쿠키 선택시에는 CSRF 공격이 가능해서 SameSite설정을 해야한다.
-
-
채팅방 생성 시 중복 검사
동일한 채팅방에 참여하고 있음에도 불구하고 동일한 채팅방을 생성하려고 할 때 기존에 존재하는 채팅방인지 검사하는 로직을 추가하였습니다.
1:1 채팅방은 채팅방 정보에 상대방의 유저 아이디를 저장해두어 A유저가 B유저 서로 동일한 채팅방을 중복으로 생성하지 않도록 하였습니다. 같이하기 채팅방과 팀매칭 채팅방은 각 모집글의 아이디를 저장하여 중복 생성을 방지 하였고, 모집이 완료된 시점에서 채팅방 생성을 단 한번만 할 수 있도록 하여 클라이언트 레벨에서도 중복 생성을 할 수 없게 설정하였습니다.
-
리스트 조회 시 채팅방 타입에 따른 정보 반환
채팅방 타입에 따라 채팅 리스트에서 보여야 하는 내용이 상이하기 때문에 유형별로 채팅방 제목, 채팅방 이미지가 다르게 보일 수 있도록 설정했습니다.
-
redis를 통한 과거 메세지 내역 조회
유저가 참여한 채팅방 마다 readIndex 라는 값을 유저가 참여한 채팅방 정보에 함께 저장하였습니다. 그리고 이 readIndex 를 기준으로 과거 내역을 요청할 수 있도록 설정하였습니다.
특히 메세지가 전송될 때 DB와 Redis 에 모두 저장이 되게 하여 과거 내역을 조회할 때도 Redis 를 먼저 조회하여 DB 에 직접 접근하는 횟수를 줄여 성능을 향상 시켰습니다. 또한 Redis TTL 을 12시간으로 설정하여 저장 공간을 효율적으로 사용할 수 있게 하였습니다.
문서: Notion 활용
소통: Slack, KakaoTalk 활용
- 구름 풀스택 2회차 최종 프로젝트 인기상 수상 - 발표(24/02/22) PPT
- 피그마 와이어프레임