크리스마스 시즌마다 유행하던 내 트리를 꾸며줘 를 모티브로 생일인 사람에게 케이크를 주면서 생일축하해주는 롤링페이퍼 서비스 입니다.
현재 서버 닫힘
리팩토링 중 (commit history, testcode 추가예정)
[배포 사이트]
https://www.naekkukae.store/
[프론트 깃허브 주소]
https://github.com/ssu-uky/cake-front.git
[백엔드 깃허브 주소]
https://github.com/ssu-uky/cake-server.git
[API 문서]
https://birthday-cake.gitbook.io/naekkukae/
기간 : 3주
프론트엔드 1명, 백엔드 1명으로 진행
대면으로 개발 진행
- Simple JWT 사용으로 로그인 보안 강화
- 로그인 시 보안을 위해 토큰을 local Storage 와 Session Storage 에 따로 분리
- 이메일 가입 시 이메일 인증 필수
- 카카오톡 소셜로그인 구현
- 가입 한 type 구별
- 본인의 편지만 오픈 가능
- 비밀번호 변경 및 분실 시 이메일로 받은 인증 링크에서만 변경 가능
(카카오톡으로 가입했을 경우, 카카오톡에 연동되어있는 이메일로 인증 요청 이메일이 보내집니다.)- 피드백 요청 기능
- 비속어 작성 차단 기능
- 사용자는 로그인을 한 후에 본인의 테이블을 원하는 색으로 만듭니다.
- 테이블은 만든 사람에게는 고유의 주소가 주어집니다.
- 그 주소를 복사하여, 다른 사람들에게 주면 로그인을 하지 않은 사람들도 케이크를 고른 후, 편지를 쓸 수 있습니다.
- 편지를 쓰면, 받은 편지(케이크)의 갯수와 방문자가 고른 케이크가 사용자의 테이블에 올려집니다.
4-1. 비속어가 들어 있을 경우, 편지는 post 되지 않습니다.- 받은 편지는 사용자만 읽을 수 있습니다.
class KakaoSignView(APIView):
def get(self, request):
client_id = KAKAO_REST_API_KEY
redirect_uri = "https://manage.naekkukae.store/auth/kakao/callback"
return redirect(
f"https://kauth.kakao.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code"
)
class KakaoCallbackView(APIView):
def get(self, request):
try:
code = request.GET.get("code")
client_id = KAKAO_REST_API_KEY
redirect_uri = "https://manage.naekkukae.store/auth/kakao/callback"
token_request = requests.post(
"https://kauth.kakao.com/oauth/token",
data={
"grant_type": "authorization_code",
"client_id": client_id,
"redirect_uri": redirect_uri,
"code": code,
},
)
token_json = token_request.json()
error = token_json.get("error", None)
if error is not None:
return Response({"message": "INVALD_CODE"}, status=HTTP_400_BAD_REQUEST)
access_token = token_json.get("access_token")
refresh_token = token_json.get("refresh_token")
profile_request = requests.get(
"https://kapi.kakao.com/v2/user/me",
headers={"Authorization": f"Bearer {access_token}"},
)
profile_json = profile_request.json()
kakao_account = profile_json.get("kakao_account")
email = kakao_account.get("email", None)
nickname = kakao_account.get("profile").get("nickname", None)
except KeyError:
return Response({"message": "INVALID_TOKEN"}, status=HTTP_400_BAD_REQUEST)
if User.objects.filter(email=email).exists():
kakao_user = User.objects.get(email=email)
tokens = RefreshToken.for_user(kakao_user)
response = HttpResponseRedirect(
f"https://naekkukae.store/KakaoLogin?refresh={str(tokens)}&access={str(tokens.access_token)}&user_pk={kakao_user.pk}"
)
return response
else:
if email:
user = User.objects.create(
email=email,
name=nickname,
social_type="kakao",
is_active=True, # 카카오로 회원가입 한 유저는 이메일 인증 필요없음 (항상 is_active=True로 설정)
)
tokens = RefreshToken.for_user(user)
response = HttpResponseRedirect(
f"https://naekkukae.store/KakaoLogin?refresh={str(refresh_token)}&access={str(tokens.access_token)}&user_pk={user.pk}"
)
# return Response(response, id, status=HTTP_200_OK)
return response
else:
return Response(
{"message": "카카오 아이디 혹은 카카오 이메일이 없습니다."},
status=HTTP_400_BAD_REQUEST,
)
이번 프로젝트로 넥스트를 처음으로 접해보았는데 넥스트 완전 사기캐인 것 같다..
그래도 프론트를 직접 개발해보니 서버와의 이해도가 훨씬 높아졌다.
개발하다가 시간이 부족하고 더 넣고 싶은 기능이 많아서 프로젝트가 끝난 후에도 혼자서 손을 봤지만, 하다보니 계속 추가하고 싶은 기능이 생기고 있다.
시간이 나면 추가하고 싶은 기능들을 정리하고, 추가해서 개발해보아야겠다.
글 잘 봤습니다, 감사합니다.