Skip to content

Commit

Permalink
Merge pull request #64 from resum-ai/feat/login
Browse files Browse the repository at this point in the history
Feat/login
  • Loading branch information
yjoonjang authored Mar 31, 2024
2 parents f5122c3 + 0c015e6 commit 7d89842
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 65 deletions.
7 changes: 3 additions & 4 deletions accounts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ def custom_signup(self, request, user):
user.save()


class UserLoginSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ("username", "email")
class KakaoTokenSerializer(serializers.Serializer):
access_token = serializers.CharField()
code = serializers.CharField()


class UserInfoUpdateSerializer(serializers.ModelSerializer):
Expand Down
95 changes: 46 additions & 49 deletions accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import environ
from pathlib import Path
from django.db import transaction
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiExample
from drf_spectacular.utils import (
extend_schema,
OpenApiResponse,
OpenApiExample,
OpenApiParameter,
)
from django.http import JsonResponse

import requests
Expand All @@ -19,7 +24,11 @@
from dj_rest_auth.registration.views import SocialLoginView
from allauth.socialaccount.providers.kakao import views as kakao_view
from .models import CustomUser
from .serializers import UserInfoUpdateSerializer, GetUserInfoSerializer
from .serializers import (
UserInfoUpdateSerializer,
GetUserInfoSerializer,
KakaoTokenSerializer,
)
import logging

logger = logging.getLogger(__name__)
Expand All @@ -41,70 +50,48 @@

@extend_schema(
summary="카카오 로그인",
description="카카오 로그인 페이지로 리다이렉트합니다.",
responses={
302: OpenApiResponse(
description="Redirects to the Kakao login page.", response=None
)
},
description="카카오 로그인 페이지로 리다이렉트하여, 정보를 입력하면 카카오 **access_token, code**를 반환합니다.",
responses={200: KakaoTokenSerializer},
)
@api_view(["GET"])
@permission_classes([AllowAny])
def kakao_login(request):
print("hi")
def kakao_login():
return redirect(
f"https://kauth.kakao.com/oauth/authorize?client_id={REST_API_KEY}&redirect_uri={KAKAO_CALLBACK_URI}&response_type=code"
)


# @extend_schema(exclude=True)
# @permission_classes([AllowAny])
# def finish_login(data):
# accept = requests.post(f"{BASE_URL}accounts/kakao/login/finish/", data=data)
# return accept

# @extend_schema(exclude=True)
@permission_classes([AllowAny])
def kakao_callback(request):
logger.warning("kakao callback")
code = request.GET.get("code")
logger.warning(f"code: {code}")

# Access Token Request
token_req = requests.get(
f"https://kauth.kakao.com/oauth/token?grant_type=authorization_code&client_id={REST_API_KEY}&client_secret={CLIENT_SECRET}&redirect_uri={KAKAO_CALLBACK_URI}&code={code}"
)
logger.warning(f"token_req: {token_req}")

token_req_json = token_req.json()
logger.warning(f"token_req_json: {token_req_json}")

error = token_req_json.get("error")
if error is not None:
raise JSONDecodeError(error)

access_token = token_req_json.get("access_token")
logger.warning(f"access_token: {access_token}")

# Email Request

profile_request = requests.get(
"https://kapi.kakao.com/v2/user/me",
headers={"Authorization": f"Bearer {access_token}"},
)
profile_data = profile_request.json()
logger.warning(f"profile_data: {profile_data}")

kakao_oid = profile_data.get("id")
kakao_account = profile_data.get("kakao_account")
username = kakao_account["profile"]["nickname"]
profile_image_url = kakao_account["profile"]["profile_image_url"]
email = kakao_account.get("email")

# 회원가입, 로그인 로직

data = {"access_token": access_token, "code": code}
logger.warning(f"data: {data}")
# TODO 유저 프로필 이미지 저장하도록
return JsonResponse(data)

Expand Down Expand Up @@ -156,38 +143,49 @@ def kakao_callback(request):
# accept_json["userProfile"]["id"] = accept_json["userProfile"].pop("pk")
# return JsonResponse(accept_json)


# @extend_schema(exclude=True)
@extend_schema(
summary="카카오 로그인 마무리",
description="access token, code를 post 요청으로 보내면 access token, 유저 정보를 반환합니다.",
# responses={
# 200: OpenApiResponse(
# description="Redirects to the Kakao login page.", response=None
# )
# },
description="access token, code를 post 요청으로 보내면 access token, 유저 정보를 반환합니다. **(id_token은 불필요합니다.)**",
parameters=[
OpenApiParameter(
name="access_token",
type=str,
description="발급받은 카카오의 access_token 입니다.",
),
OpenApiParameter(
name="code", type=str, description="발급받은 카카오의 code 입니다."
),
],
request={
"application/json": {
"type": "object",
"properties": {
"access_token": {"type": "string"},
"code": {"type": "string"},
},
},
},
examples=[
OpenApiExample(
response_only=True,
summary="Response Body Example입니다.",
name="success_example",
value={
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlI",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBl",
"user": {
"pk": 6,
"email": "[email protected]"
}
},
),
],
OpenApiExample(
response_only=True,
summary="Response Body Example입니다.",
name="success_example",
value={
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlI",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBl",
"user": {"pk": 6, "email": "[email protected]"},
},
),
],
)
class KakaoLoginView(SocialLoginView):
adapter_class = kakao_view.KakaoOAuth2Adapter
client_class = OAuth2Client
callback_url = KAKAO_CALLBACK_URI



class UpdateUserInfoView(APIView):
permission_classes = [IsAuthenticated] # 인증된 사용자만 접근 가능하도록 설정

Expand Down Expand Up @@ -219,4 +217,3 @@ def get(self, request):
user = request.user
serializer = GetUserInfoSerializer(user)
return Response(serializer.data)

7 changes: 4 additions & 3 deletions resumai/middleware.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from django.http import HttpResponse


class HealthCheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
if request.path == '/health':
return HttpResponse('ok')
return self.get_response(request)
if request.path == "/health":
return HttpResponse("ok")
return self.get_response(request)
6 changes: 1 addition & 5 deletions resumai/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = f"{os.environ.get('DJANGO_SECURE_KEY')}"
# ALLOWED_HOSTS = ["127.0.0.1", "api.resumai.kr", "resumai.kr"]
ALLOWED_HOSTS = ["*"]
ALLOWED_HOSTS = ["127.0.0.1", "*.resumai.kr", "resumai.kr", "localhost:3000"]

# Application definition

Expand Down Expand Up @@ -201,6 +200,3 @@
"version": 1, # the dictConfig format version
"disable_existing_loggers": False, # retain the default loggers
}



6 changes: 3 additions & 3 deletions resumai/settings/prod.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

SECURE_HSTS_SECONDS = 31536000
# SECURE_SSL_REDIRECT = True
CSRF_TRUSTED_ORIGINS=['https://*.resumai.kr']
CSRF_TRUSTED_ORIGINS = ["https://*.resumai.kr"]
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_HSTS_PRELOAD=True
SECURE_HSTS_PRELOAD = True
# SECURE_HSTS_INCLUDE_SUBDOMAINS=True
SESSION_COOKIE_SECURE=True
SESSION_COOKIE_SECURE = True
4 changes: 3 additions & 1 deletion resumai/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@
permission_classes=[permissions.AllowAny],
)


def preprocessing_filter_spec(endpoints):
filtered = []
for path, path_regex, method, callback in endpoints:
# Remove all but DRF API endpoints
if (not path.startswith("/registration/")):
if not path.startswith("/registration/"):
filtered.append((path, path_regex, method, callback))
return filtered


urlpatterns = [
path("", kakao_login_page, name="home"),
path("admin/", admin.site.urls),
Expand Down

0 comments on commit 7d89842

Please sign in to comment.