프로젝트

📌 Django OAuth 리팩토링 - 2편: OAuth Callback + JWT 쿠키 연동

Chansman 2025. 6. 13. 00:53

📌 Django OAuth 리팩토링 - 2편: OAuth Callback + JWT 쿠키 연동

✅ 네이버/깃허브 로그인 후 콜백 처리부터
✅ 최초 로그인 유저 → 닉네임 입력 → 회원가입 처리
✅ JWT를 쿠키에 심어 자동 로그인 구현까지!


🔄 1. OAuth 콜백 구조 이해

✔️ 로그인 과정

  1. /oauth/naver/login/ or /oauth/github/login/ 접속 시 → 각 플랫폼 인증 URL로 리디렉션
  2. 로그인 성공 → callback URL로 code + state 쿼리 파라미터 전달
  3. 이 값을 바탕으로 access_token 요청 및 사용자 프로필 획득

🧩 2. 콜백 뷰 리팩토링 (oauth_views.py)

🔄 기존 form 기반 → ✅ API 기반 리팩토링

class NaverLoginRedirectView(RedirectView):
    def get_redirect_url(self, *args, **kwargs):
        ...
        return f'{NAVER_LOGIN_URL}?{urlencode(params)}'

콜백 함수 예시:

def naver_callback(request):
    ...
    access_token = get_naver_access_token(code, state)
    profile = get_naver_profile(access_token)
    
    email = profile.get('email')
    user = User.objects.filter(email=email).first()

    if user:
        login(request, user)
        return set_jwt_cookie(redirect('main'), user)
    return redirect(f"{BASE_URL}/oauth/nickname/?access_token={access_token}&oauth=naver")

🌱 3. 최초 유저 닉네임 입력 처리

최초 로그인 유저는 닉네임이 없으므로 /oauth/nickname/에서 닉네임을 입력 받아 회원가입 처리한다.

@api_view(['POST'])
def oauth_nickname(request):
    access_token = request.query_params.get('access_token')
    oauth = request.query_params.get('oauth')

    ...
    serializer = NicknameSerializer(data=request.data)
    if serializer.is_valid():
        nickname = serializer.validated_data['nickname']
        profile = get_naver_profile(access_token)  # or github
        ...
        user = User(email=email, nickname=nickname, is_active=True)
        user.set_password(User.objects.make_random_password())
        user.save()
        return set_jwt_cookie(Response(...), user)

🍪 4. 쿠키 기반 JWT 인증 적용

✅ JWT + 쿠키 조합 방식

  • access_token, refresh_token을 HttpOnly 쿠키에 저장
  • 로그인 이후 클라이언트가 Authorization 헤더를 다루지 않아도 자동 인증
def set_jwt_cookie(response: HttpResponse, user: User) -> HttpResponse:
    refresh = RefreshToken.for_user(user)
    access_token = str(refresh.access_token)
    
    response.set_cookie("access_token", access_token, httponly=True, secure=not DEBUG)
    response.set_cookie("refresh_token", str(refresh), httponly=True, secure=not DEBUG)
    return response

🛡️ 5. 주의사항 & 팁

  • ❗ @csrf_exempt 제거됨 → 대신 쿠키 기반 JWT 인증이므로 CSRF 우회 가능
  • ❗ nickname은 유일성 보장 → serializer에서 validate_nickname 처리
  • 🔐 @api_view(['POST'])로 POST 기반 처리

✅ 최종 URL 구성 (oauth_urls.py)

urlpatterns = [
    path('naver/login/', NaverLoginRedirectView.as_view()),
    path('naver/callback/', naver_callback),
    path('github/login/', GithubLoginRedirectView.as_view()),
    path('github/callback/', github_callback),
    path('nickname/', oauth_nickname),
]

🧪 Swagger로 API 테스트

  • /oauth/naver/login/ → 인증 시작
  • /oauth/nickname/ → 닉네임 POST 제출
  • ✅ 자동 로그인 + 쿠키 발급까지 완료!

이제 시리즈 3 넘어갈 준비 됐어
"다음"이라고 입력하면 다음 블로그 내용 바로 정리해줄게 💪