From 20e53471d9cfbbb12a392ea97e128466332a879d Mon Sep 17 00:00:00 2001 From: subin <200516bb@gmail.com> Date: Mon, 24 Jul 2023 23:57:51 +0900 Subject: [PATCH] feat: kakao social signup api --- app/api/user.py | 69 ++++++++++++++++++++++++++++++++++++++--------- app/utils/user.py | 20 +++++++++++++- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/app/api/user.py b/app/api/user.py index ea022fb..d2b1399 100644 --- a/app/api/user.py +++ b/app/api/user.py @@ -6,7 +6,7 @@ import os import requests -from app.models.user import User +from app.models.user import SocialAuth, User from app.utils.user import UserDTO, UserService from app.decorators.login_required import login_required from app.utils.error_handler import InvalidTokenError @@ -54,6 +54,17 @@ 'device_token': fields.String(required=True, default='device_token', description='device token') }) +SocialUserModel = user.model('SocialUser', { + 'name': fields.String(required=True, default='name', description='user name'), + 'gender': fields.String(required=True, default='여', description='user gender'), + 'birth': fields.Date(required=True, default='2023-03-20', description='user birth'), + 'phone': fields.String(required=True, default='01012345678', description='user phone'), + 'social_id': fields.String(required=True, default='2930588672', description='user social id'), + 'connected_at': fields.DateTime(required=True, default='2023-07-24T11:06:43Z', description='connected at'), + 'type': fields.String(required=True, default='kakao', description='connected at'), + 'access_token': fields.String(required=True, default='access_token', description='access token') +}) + @user.route('/signup', methods=['POST']) class SignUp(Resource): @user.expect(userModel) @@ -332,7 +343,7 @@ class KakaoOauth(Resource): @user.doc(responses={400: 'Bad Request'}) def get(self): code = str(request.args.get('code')) - + oauth_token = requests.post( url="https://kauth.kakao.com/oauth/token", headers={ @@ -347,15 +358,49 @@ def get(self): }, ).json() - return { 'code': code } - # access_token = oauth_token["access_token"] - # profile_request = requests.get( - # "https://kapi.kakao.com/v2/user/me", headers={"Authorization": f"Bearer {access_token}"} - # ).json() + kakao_access_token = oauth_token["access_token"] + profile_request = requests.get( + "https://kapi.kakao.com/v2/user/me", headers={"Authorization": f"Bearer {kakao_access_token}"} + ).json() + + u = SocialAuth.query.filter_by(id=str(profile_request['id'])).first() + if u: + #login + access_payload = { + 'id': str(u.user_id), + 'access_token_exp': (datetime.datetime.now() + datetime.timedelta(minutes=60*24)).isoformat() + } + access_token = jwt.encode(access_payload, os.getenv('SECRET_KEY'), algorithm="HS256") + + refresh_payload = { + 'id': str(u.user_id), + 'refresh_token_exp': (datetime.datetime.now() + datetime.timedelta(minutes=60*24*60)).isoformat() + } + refresh_token = jwt.encode(refresh_payload, os.getenv('SECRET_KEY'), algorithm="HS256") + return { 'access_token': access_token, 'refresh_token': refresh_token, 'user_id': u.id }, 200 + else: + #signup + info = { + 'id': profile_request['id'], + 'connected_at': profile_request['connected_at'], + 'access_token': kakao_access_token + } + return info - # info = { - # 'id': profile_request['oauth_token']['id'], - # 'connected_at': profile_request['oauth_token']['connected_at'] - # } - # return info \ No newline at end of file +@user.route('/oauth/signup', methods=['POST']) +class OauthSignUp(Resource): + @user.doc(responses={200: 'OK'}) + @user.doc(responses={400: 'Bad Request'}) + @user.expect(SocialUserModel) + def post(self): + content = request.json + user_dto = UserDTO( + name=content['name'], + gender=content['gender'], + birth=content['birth'], + phone=content['phone'] + ) + UserService.create_user(user_dto) + UserService.create_social_auth(user_dto, content) + return { 'message': '회원가입 되었습니다' }, 200 \ No newline at end of file diff --git a/app/utils/user.py b/app/utils/user.py index b43eff6..456cc72 100644 --- a/app/utils/user.py +++ b/app/utils/user.py @@ -4,7 +4,7 @@ from app.utils.error_handler import SignUpFail, UserFail import datetime from app.models import db -from app.models.user import User, Notification, UserNotification +from app.models.user import SocialAuth, User, Notification, UserNotification import bcrypt import re from flask import g @@ -165,6 +165,24 @@ def create_user(user) -> 'UserDTO': db.session.commit() return user_dto + + def create_social_auth(user_dto, content): + social_user = SocialAuth( + id=content['id'], + user_id=user_dto.id, + connected_at=content['connected_at'], + social_type=content['type'], + access_token=content['access_token'] + ) + try: + db.session.add(social_user) + db.session.commit() + except Exception as e: + db.session.rollback() + db.session.close() + raise SignUpFail('소셜 유저 회원가입에 실패했습니다.') + + def update_phone(phone) -> UserDTO: """ 유저의 전화번호를 수정합니다.