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 a59b54c..bbda12e 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.auth.backends.ModelBackend", + "allauth.account.auth_backends.AuthenticationBackend", ] REST_FRAMEWORK = { @@ -57,8 +72,17 @@ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + + #kakao + 'allauth.account.middleware.AccountMiddleware', ] - +#소셜로그인 동작설정 +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 = [ @@ -120,6 +144,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..c367673 100644 --- a/config/urls.py +++ b/config/urls.py @@ -15,9 +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 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