BE 테크스펙(User) - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
- 회원가입과 로그인 기능을 구현하고 유저별 마이페이지와 활동페이지의 테크스펙을 정의한다.
- 결과 1 : 카카오 OAuth2를 통한 로그인 및 회원가입 기능 구현
- 결과 2 : 마이페이지와 활동페이지를 통한 개인화된 정보제공
- 결과 3 : 앨범, 피드 관련 활동에 대한 알림기능 구현
- 회원 탈퇴는 정의하지 않는다.
- 카카오를 제외한 다른 OAuth는 정의하지 않는다.
-
유저
-
토큰 관리
-
알림
- 로그인
- 로그인 요청
- endpoint :
/api/auth
- 구현 상세 :
- request param 해당없음
- 처리로직 :
- 유저는 서버에 로그인 요청 api를 요청한다.
- 해당 유저에게 kakao REST_API_KEY와 REDIRECT_URI가 포함된 헤더를 리턴한다.
- 유저는 전달받은 URL로 리다이렉트되어 카카오 로그인을 수행한다.
- 카카오 로그인이 성공하면 카카오로부터 authorization_code를 발급받는다.
- 발급받은 코드를 서비스 로그인 시 사용한다.
- endpoint :
- 서비스 로그인
- endpoint =
/api/auth/callback?code={authorization_code}
- 구현 상세
- request param : authorization_code
- 처리로직 :
-
/api/auth
를 통해 리다이렉트된 유저는 카카오 페이지에서 카카오 로그인을 수행한다. - authorization_code를 query string으로 서버에 보낸다.
- 서버는 전달받은 코드를
https://kauth.kakao.com/oauth/token
로 보내 토큰 발급 요청을 한다. - 정상적인 코드라면 Access token과 Refresh token과 profile_image를 받는다.
- id토큰의 picture(프로필사진)과 sub(유저 아이디), email(유저이메일)을 파싱한다.
- 만약 sub가 User 테이블에 이미 있다면 로그인 처리하고, 만약 그렇지 않다면 회원가입 후 로그인 처리 한다.
- 로그인 처리는 자체 JWT토큰(access token, refresh token) 발급하여 유저에게 응답으로 전송하며, 서버는 refresh token만을 보관한다.
- refresh token 보관 장소는 redis이다.
-
- endpoint =
- 유저 정보 확인
- endpoint =
/api/user/{userId}
- 구현상세
- request header :
access token
필수 - 처리로직 :
- 클라이언트가 보유한 access token을 기반으로 로그인된 유저의 정보를 확인한다.
- 캐싱하고 있는 유저정보가 만료되면 자동으로 유저정보를 요청하여 갱신한다.
- 프로필, 닉네임과 같은 기본정보와
cacheTil
과 같은 캐시 유효시간이 포함되어 있다. 이를 사용하여 유저정보를 캐싱한다.
- request header :
- endpoint =
- 만료 토큰 재발급
- endpoint =
/api/auth/refresh
- 구현상세
- request body :
refresh token
- 처리로직
- access token이 만료되었을 때 재발급 요청을 한다. 이때 보유하고 있는 refresh token을 서버에 전송한다.
- 서버는 refresh token을 redis에 저장된 값과 확인하여 일치하는지 아닌지 확인한다.
- 만약 토큰 유효성이 통과된다면 access token을 새로 발급한다.
- refresh token이 만료되거나 유효하지 않다면 로그아웃시키고 다시 로그인하게 한다.
- request body :
- endpoint =
- 로그인 요청
- 마이페이지
- 유저 사진 수 월별 조회(단위 : 일)
- endpoint =
/api/user/statistics/picture/?yearmonth={yearMonth}
- 구현상세
- request param : yearMonth(yyyy-mm)
- 해당 값은 비어있을 수 있음. 비어있으면 유저가 등록한 모든 사진 수 반환
- 처리로직
- 먼저 header로 전달받는 access token의 userId를 파싱한다.
- Picture 테이블에서 userId와 yearMonth와 일치하는 데이터를 조회한다.
- 조회한 데이터 수를 일자별로 리턴한다.
- MVP는 테이블에서 읽는 방식으로 개발하고, v2에서는 redis에 캐싱한다.
- request param : yearMonth(yyyy-mm)
- endpoint =
- 유저 방문 장소 조회
- endpoint =
/api/user/statistics/place?yearMonth={yearMonth}
- 구현상세
- request param : yearMonth(yyyy-mm)
- 해당 값은 비어있을 수 있음. 비어있으면 유저가 방문한 모든 장소의 숫자만 반환
- 처리로직
- 먼저 header로 전달받는 access token의 userId를 파싱한다.
- Picture 테이블과 Place 테이블을 조인하여 userId별 장소를 yearMonth 조건에 맞추어 조회한다.
- 조회한 데이터를 리턴한다.
- MVP는 테이블에서 읽는 방식으로 개발하고, v2에서는 redis에 캐싱한다.
- request param : yearMonth(yyyy-mm)
- endpoint =
- 유저 사진 수 월별 조회(단위 : 일)
- 알림
- 알림 조회
- endpoint =
/api/notification?cursor={lastNotificationId}
- 구현상세
- request param : lastNotificationId
- null이면 최신 알림부터 조회 시작
- 처리 로직
- 먼저 header로 전달받는 access token의 userId를 파싱한다.
- lastNotificationId가 null이면:
- userId 기준으로 가장 최근 알림부터 (createdAt 내림차순) size(20) 만큼 조회한다.
- lastNotificationId가 존재하면:
- lastNotificationId보다 작은(id < lastNotificationId) 알림들을
- userId 기준, createdAt 내림차순으로 size(20) 만큼 조회한다.
- 다음 커서를 계산한다.
- 조회된 알람 중 가작 마지막 알림의 id를 nextCursor로 지정
- 만약 가져온 알림이 20보다 작으면 hasNext=False로 표시한다.
- 알림 리스트, nextCursor, hasNext를 포함한 응답을 반환한다.
- request param : lastNotificationId
- endpoint =
- 알림 읽음
- endpoint =
/api/notification/{notificationId}/status
- 구현상세
- request param :
notificationId
- 처리 로직
- 먼저 header로 전달받는 access token의 userId를 파싱한다.
- userId에 해당하는 notificationId를 조회한다.
- 해당 알림의 is_read를 true로 변경한다.
- 알림 읽음 처리 성공 응답을 반환한다.
- request param :
- endpoint =
- 알림 조회
🤔 이 섹션은 왜 필요한가요?
- 설계 및 기술자료에서 구현하는데 추가적으로 필요한 기술들을 명시합니다.
🤔 이 섹션은 왜 필요한가요?
- 주요 설계 외에 추가적으로 고민했거나, 특별히 주의해야 할 점, 혹은 내린 결정의 배경 등을 기록합니다.
- 성능, 보안, 확장성, 장애 대응 등 다양한 측면에서의 고려사항을 담을 수 있습니다.
🤔 이 섹션은 왜 필요한가요?
- 설계나 구현 과정에서 아직 결정되지 않았거나, 다른 팀/동료의 의견이 필요한 부분을 명시합니다.
- 협업을 촉진하고, 기술적인 결정에 대한 합의를 이끌어내는 데 도움을 줍니다.
🤔 이 섹션은 왜 필요한가요?
- 프로젝트 내에서 사용되는 특정 용어, 약어, 상태 값 등의 의미를 명확히 정의합니다.
- 팀원 간의 오해를 줄이고 원활한 의사소통을 돕습니다.