From 9335e0124bbcd5cc17af143ffe38536e0c9eff5b Mon Sep 17 00:00:00 2001 From: hyunnminn <65217613+StormtroopeR2727@users.noreply.github.com> Date: Sat, 8 Aug 2026 04:20:06 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=EC=B9=B4=EC=B9=B4=EC=98=A4=ED=86=A1?= =?UTF-8?q?=20allauth=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/settings.py | 34 +++++++++++++++++++++++++++++++++- config/urls.py | 1 + requirements.txt | 3 +++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/config/settings.py b/config/settings.py index a59b54c..f7bfdeb 100644 --- a/config/settings.py +++ b/config/settings.py @@ -9,12 +9,14 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/6.0/ref/settings/ """ - +import os from pathlib import Path +from dotenv import load_dotenv # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +load_dotenv(BASE_DIR / ".env") # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ @@ -40,6 +42,19 @@ 'rest_framework', 'accounts', + + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'allauth.socialaccount.providers.kakao', +] + +SITE_ID=1 + +#kakao +AUTHENTICATION_BACKENDS= [ + "django.contrib.backends.ModelBackend", + "allauth.account.auth_backends.AuthenticationBackend", ] REST_FRAMEWORK = { @@ -57,7 +72,15 @@ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + + #kakao + 'allauth.account.middleware.AccountMiddleware', ] +#소셜로그인 동작설정 +SOCIALACCOUNT_LOGIN_ON_GET = True # 버튼 클릭시 중간확인없이 바로 카카오로 이동 +SOCIALACCOUNT_EMAIL_REQUIRED = False # 카카오가 이메일 안줘도 가입가능 +SOCIALACCOUNT_EMAIL_VERIFICATION = 'none' # 소셜가입시 이메일 인증절차 생략 + ROOT_URLCONF = 'config.urls' @@ -120,6 +143,15 @@ USE_TZ = True +SOCIALACCOUNT_PROVIDERS = { + "kakao": { + "APP": { + "client_id": os.environ.get("KAKAO_REST_API_KEY"), # .env에서 읽어온 REST API 키 + "secret": os.environ.get("KAKAO_CLIENT_SECRET"), # .env에서 읽어온 Client Secret + "key": "", + } + } +} # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/6.0/howto/static-files/ diff --git a/config/urls.py b/config/urls.py index 50375ae..7c78b9d 100644 --- a/config/urls.py +++ b/config/urls.py @@ -20,4 +20,5 @@ urlpatterns = [ path('admin/', admin.site.urls), path('auth/', include('accounts.urls')), + path('auth/social/', include('allauth.urls')), ] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index d32c7a0..5b257a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,6 @@ asgiref==3.12.1 Django==6.0.8 djangorestframework==3.17.2 sqlparse==0.5.5 +django-allauth==65.18.0 +python-dotenv==1.2.2 +requests==2.34.2 \ No newline at end of file From dd8c9e64e1e1731e5179a7f690266e631bf0ae28 Mon Sep 17 00:00:00 2001 From: hyunnminn <65217613+StormtroopeR2727@users.noreply.github.com> Date: Sat, 8 Aug 2026 04:51:00 +0900 Subject: [PATCH 2/3] =?UTF-8?q?adapter=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/adapters.py | 18 ++++++++++++++++++ config/settings.py | 9 +++++---- 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 accounts/adapters.py diff --git a/accounts/adapters.py b/accounts/adapters.py new file mode 100644 index 0000000..6f3948a --- /dev/null +++ b/accounts/adapters.py @@ -0,0 +1,18 @@ +# accounts/adapters.py +from allauth.account.utils import user_username +from allauth.core.exceptions import ImmediateHttpResponse +from allauth.socialaccount.adapter import DefaultSocialAccountAdapter +from allauth.socialaccount.providers.base import AuthError +from django.http import HttpResponseRedirect + + +class KakaoSocialAccountAdapter(DefaultSocialAccountAdapter): + def populate_user(self, request, sociallogin, data): + user = super().populate_user(request, sociallogin, data) + # allauth 기본값은 카카오 닉네임 기반 username이라 자체 계정과 네임스페이스가 뒤섞인다. + user_username(user, f"kakao_{sociallogin.account.uid}") + return user + + def on_authentication_error(self, request, provider, error=None, exception=None, extra_context=None): + code = "KAKAO_AUTH_DENIED" if error == AuthError.CANCELLED else "SOCIAL_AUTH_FAILED" + raise ImmediateHttpResponse(HttpResponseRedirect(f"/login?error={code}")) diff --git a/config/settings.py b/config/settings.py index f7bfdeb..bbda12e 100644 --- a/config/settings.py +++ b/config/settings.py @@ -53,7 +53,7 @@ #kakao AUTHENTICATION_BACKENDS= [ - "django.contrib.backends.ModelBackend", + "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ] @@ -77,11 +77,12 @@ 'allauth.account.middleware.AccountMiddleware', ] #소셜로그인 동작설정 -SOCIALACCOUNT_LOGIN_ON_GET = True # 버튼 클릭시 중간확인없이 바로 카카오로 이동 +SOCIALACCOUNT_LOGIN_ON_GET = False # 폼 + CSRF방어 SOCIALACCOUNT_EMAIL_REQUIRED = False # 카카오가 이메일 안줘도 가입가능 SOCIALACCOUNT_EMAIL_VERIFICATION = 'none' # 소셜가입시 이메일 인증절차 생략 - - +SOCIALACCOUNT_EMAIL_AUTHENTICATION = False # 자동연결차단 +LOGIN_REDIRECT_URL = "/" # 로그인 후 리다이렉트 주소 +SOCIALACCOUNT_ADAPTER = "accounts.adapters.KakaoSocialAccountAdapter" ROOT_URLCONF = 'config.urls' TEMPLATES = [ From 9230cc7c4cfb7c34456fa0627cc445e857d2a09b Mon Sep 17 00:00:00 2001 From: hyunnminn <65217613+StormtroopeR2727@users.noreply.github.com> Date: Sat, 8 Aug 2026 19:33:03 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=9B=84=20=EC=9E=84=EC=8B=9C=20=EB=A6=AC=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=EC=9A=A9=20placeholder=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/urls.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/config/urls.py b/config/urls.py index 7c78b9d..c367673 100644 --- a/config/urls.py +++ b/config/urls.py @@ -15,10 +15,24 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin +from django.http import JsonResponse from django.urls import path, include + +def home(request): + # TODO: 프론트엔드 구현 후 SPA index 서빙으로 교체 + return JsonResponse({"is_authenticated": request.user.is_authenticated}) + + +def login_placeholder(request): + # TODO: 프론트엔드 구현 후 로그인 페이지로 교체 + return JsonResponse({"error": request.GET.get("error")}) + + urlpatterns = [ path('admin/', admin.site.urls), + path('', home, name='home'), + path('login', login_placeholder, name='login-placeholder'), path('auth/', include('accounts.urls')), path('auth/social/', include('allauth.urls')), ] \ No newline at end of file