Skip to content

[Feat] django-allauth 기반 카카오 소셜로그인 추가 #5

Description

@hyunnminn

📌 개요

django-allauth를 도입해 카카오 OAuth2 소셜로그인을 추가한다. 기존 자체 세션 로그인은 그대로 유지하며, 두 경로 모두 동일한 Django 세션을 발급한다.

🎯 배경 / 목적

  • 아이디·비밀번호 입력 부담으로 인한 초기 진입 이탈을 줄이기 위해 간편 로그인 경로를 추가한다.
  • 기존 자체 계정 사용자를 강제 마이그레이션하지 않기 위해 대체가 아닌 병행으로 간다.
  • OAuth2 흐름(state 검증, 토큰 교환, 사용자 정보 조회)을 직접 구현하지 않고 검증된 라이브러리에 위임한다.
  • 인증 방식(세션 쿠키)은 그대로이므로 기존 16개 인증 필요 엔드포인트는 영향받지 않는다.
  • 자체 계정과 카카오 계정은 완전히 분리된 별개 계정으로 취급하며, 계정 연결은 제공하지 않는다.

✅ 작업 내용

사전 준비

  • 패키지 설치: django-allauth==65.18.0, python-dotenv, requests
  • requirements.txt 갱신 및 팀원 공유
  • 카카오 개발자 콘솔 앱 생성, 카카오 로그인 활성화
  • Redirect URI 등록 — 로컬 http://localhost:8000/auth/social/kakao/login/callback/
  • Redirect URI 등록 — 배포 https://{도메인}/auth/social/kakao/login/callback/
  • 동의 항목 설정 (닉네임 필수동의 / 이메일은 계정 분리 정책상 불필요 — 미결 [Feature] #1 세션 기반 인증 API 구현  #4)
  • REST API 키 + Client Secret 발급, .env 저장 및 .gitignore 확인

settings 설정

  • INSTALLED_APPSdjango.contrib.sites, allauth, allauth.account, allauth.socialaccount, allauth.socialaccount.providers.kakao 추가
  • SITE_ID = 1
  • AUTHENTICATION_BACKENDSModelBackend(선순위) + allauth.account.auth_backends.AuthenticationBackend
  • MIDDLEWAREallauth.account.middleware.AccountMiddleware 추가
  • SOCIALACCOUNT_LOGIN_ON_GET = FalsePOST 폼 방식 채택 (CSRF 방어)
  • SOCIALACCOUNT_EMAIL_REQUIRED = False, SOCIALACCOUNT_EMAIL_VERIFICATION = "none"
  • SOCIALACCOUNT_EMAIL_AUTHENTICATION = False이메일 자동 계정 연결 차단 (필수)
  • SOCIALACCOUNT_STORE_TOKENS = False — 카카오 토큰 미저장 (미결 [Feature] 카카오 로그인기능 작성 #6)
  • LOGIN_REDIRECT_URL = "/" — 프로필 분기는 GET /auth/session에 위임
  • SOCIALACCOUNT_PROVIDERS.env에서 읽은 client_id/secret 등록
  • base.py/local.py/prod.py 설정 분리 구조에 맞게 배치

URL 연결

  • path("auth/social/", include("allauth.urls")) 추가 — 기존 auth/ 라우팅보다 뒤에 배치
  • 기존 /auth/login, /auth/signup, /auth/logout 경로가 영향받지 않는지 확인
  • python manage.py migrateSocialApp/SocialAccount/SocialToken 테이블 생성

커스텀 어댑터 (accounts/adapters.py)

  • DefaultSocialAccountAdapter 상속 클래스 작성, SOCIALACCOUNT_ADAPTER로 등록
  • populate_user 오버라이드 → username을 kakao_{uid}로 고정
  • 신규 User에 set_unusable_password() 적용
  • on_authentication_error 오버라이드 → /login?error={code} 리다이렉트
    • 동의 취소 → KAKAO_AUTH_DENIED
    • 그 외 인증 오류 → SOCIAL_AUTH_FAILED
  • is_auto_signup_allowed 확인 — 중간 가입 폼 없이 바로 생성되는지

기존 엔드포인트 수정 (최소 범위)

  • GET /auth/session 응답에 login_method 필드 추가
  • POST /auth/signup username 검증에 kakao_ 예약어 차단 추가
  • POST /auth/signuplogin() 호출에 backend="...ModelBackend" 명시 — 누락 시 에러
  • POST /auth/login 코드 변경 없음 — 회귀 테스트만 추가
  • POST /auth/logout 변경 없음 — unlink 미호출 방침 주석 명시

프론트엔드

  • 로그인 화면에 카카오 버튼 추가 — <form method="post"> + {% csrf_token %}
    ({% load socialaccount %}, action="{% provider_login_url 'kakao' %}")
  • 카카오 브랜드 가이드 준수 (배경 #FEE500, 텍스트 #000000D9, 심볼 포함)
  • "가입할 때 사용한 방식으로 로그인해주세요" 안내 문구 상시 노출 (계정 분리 정책상 필수)
  • /login?error= 쿼리 파싱 및 문구 매핑
  • 설정 화면에서 login_method === "kakao"이면 비밀번호 변경 메뉴 숨김

테스트

  • 카카오 응답 mocking 기반 콜백 테스트 (신규 가입 / 재로그인)
  • 동일 카카오 계정 재로그인 시 User 중복 생성되지 않음 검증
  • username이 닉네임이 아닌 kakao_{uid} 형식으로 생성되는지 검증
  • 인증 실패 시 allauth 에러 페이지가 아닌 /login?error=로 리다이렉트되는지 검증
  • 기존 자체 로그인·회원가입·로그아웃 테스트 전체 회귀 검증
  • SocialToken 테이블이 비어 있는지 확인 (토큰 미저장)

🔍 완료 조건

  • 카카오 계정으로 로그인하면 세션이 발급되고 새로고침해도 유지된다
  • 최초 카카오 로그인 시 User + SocialAccount가 생성되고 /signup/profile로 이동한다
  • 프로필까지 완료한 계정으로 재로그인하면 /로 이동하며 User가 중복 생성되지 않는다
  • 생성된 username이 kakao_{kakaoId} 형식이다 (카카오 닉네임이 아님)
  • 기존 자체 계정 로그인·회원가입이 이전과 동일하게 동작한다
  • 카카오 계정의 username으로 자체 로그인 시도 시 401 INVALID_CREDENTIALS가 반환된다
  • kakao_로 시작하는 아이디로 자체 회원가입이 차단된다
  • GET /auth/sessionlogin_method를 정확히 반환한다
  • 자체 계정으로 기록한 카페인 로그가 카카오 계정 로그인 시 조회되지 않는다 (분리 검증)
  • 카카오 버튼이 GET 링크가 아닌 POST 폼으로 동작한다
  • 동의 취소·인증 실패 시 로그인 화면에 적절한 문구가 노출된다
  • 카카오 계정 로그인 시 설정 화면에 비밀번호 변경 메뉴가 노출되지 않는다
  • REST API 키·Client Secret이 코드에 하드코딩되어 있지 않다
  • 배포 환경(EC2/Nginx)에서 Redirect URI가 정상 동작한다

📎 참고

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature새로운 기능 추가

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions