Project View

MMM._.MMM·2025년 1월 6일

안녕하세요! 오늘은 Django REST Framework를 사용하여 구현한 종합적인 사용자 인증 시스템에 대해 알아보겠습니다. 이 시스템은 회원가입, 로그인, 카카오 소셜 로그인, 로그아웃, 비밀번호 재설정 등의 기능을 포함하고 있습니다. 각 기능별로 코드와 함께 자세히 설명드리겠습니다.

1. 회원가입 (UserRegistrationView)

회원가입 기능은 UserRegistrationView 클래스에서 구현됩니다.

class UserRegistrationView(generics.CreateAPIView):
    queryset = CustomUser.objects.all()
    serializer_class = RegisterSerializer
    permission_classes = [AllowAny]
    authentication_classes = []

    @extend_schema(
        summary="사용자 회원가입",
        description="새로운 사용자 계정을 생성하고 JWT TOKEN 발급 (비밀번호는 8자 이상 20자 이하)",
        # ... (생략)
    )
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            refresh = RefreshToken.for_user(user)
            return Response({
                "message": "회원가입이 성공적으로 완료되었습니다",
                "username": user.username,
                "email": user.email,
                "refresh": str(refresh),
                "access": str(refresh.access_token),
            }, status=status.HTTP_201_CREATED)
        return Response({
            "message": "회원가입에 실패하셨습니다.",
            "errors": serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

이 뷰는 새로운 사용자 계정을 생성하고 JWT 토큰을 발급합니다. RegisterSerializer를 사용하여 입력 데이터의 유효성을 검사하고, 유효한 경우 사용자를 생성합니다. 성공 시 201 상태 코드와 함께 사용자 정보 및 토큰을 반환합니다.

2. 로그인 (UserLoginView)

로그인 기능은 UserLoginView 클래스에서 구현됩니다.

class UserLoginView(APIView):
    permission_classes = [AllowAny]
    authentication_classes = []

    @extend_schema(
        summary="사용자 로그인",
        description="사용자 인증 및 JWT 토큰 발급",
        # ... (생략)
    )
    def post(self, request):
        serializer = LoginSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            refresh = RefreshToken.for_user(user)
            return Response({
                "message": "로그인이 성공적으로 완료되었습니다.",
                "email": user.email,
                "username": user.username,
                "refresh": str(refresh),
                "access": str(refresh.access_token),
            }, status=status.HTTP_200_OK)
        return Response({
            "message": "로그인에 실패하셨습니다.",
            "errors": serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

이 뷰는 사용자 인증을 처리하고 로그인 성공 시 JWT 토큰을 발급합니다. LoginSerializer를 사용하여 이메일과 비밀번호를 검증하고, 인증 성공 시 토큰을 생성하여 반환합니다.

3. 카카오 소셜 로그인

카카오 소셜 로그인은 두 개의 뷰로 구현됩니다: KakaoLoginView와 KakaoCallbackView.

class KakaoLoginView(APIView):
    permission_classes = [AllowAny]

    @extend_schema(
        summary="카카오 로그인 URL 요청",
        description="카카오 로그인을 위한 인증 URL을 반환합니다.",
        responses={200: OpenApiTypes.OBJECT}
    )
    def get(self, request):
        kakao_auth_url = f"https://kauth.kakao.com/oauth/authorize?client_id={settings.KAKAO_REST_API_KEY}&redirect_uri={settings.KAKAO_REDIRECT_URI}&response_type=code"
        return Response({"auth_url": kakao_auth_url})

class KakaoCallbackView(APIView):
    permission_classes = [AllowAny]

    @extend_schema(
        summary="카카오 로그인 콜백 처리",
        description="카카오 로그인 후 받은 코드로 사용자 정보를 조회하고 로그인 처리합니다.",
        # ... (생략)
    )
    def get(self, request):
        code = request.GET.get('code')
        # 카카오 액세스 토큰 요청
        # ... (생략)
        # 카카오 사용자 정보 요청
        # ... (생략)
        # 사용자 생성 또는 조회
        # ... (생략)
        # JWT 토큰 생성
        refresh = RefreshToken.for_user(user)
        user.refresh_token = str(refresh)
        user.save()
        return Response({
            "user": UserSerializer(user).data,
            "access_token": str(refresh.access_token),
            "refresh_token": str(refresh),
        })

KakaoLoginView는 카카오 로그인 URL을 제공하고, KakaoCallbackView는 카카오 인증 후 콜백을 처리합니다. 카카오 API를 통해 사용자 정보를 받아와 계정을 생성하거나 조회하고, JWT 토큰을 발급합니다. (Kakao 소셜로그인에 관한 자세한 글은 따로 올리는 걸로....)

4. 로그아웃 (LogoutView)

로그아웃 기능은 LogoutView 클래스에서 구현됩니다.

class LogoutView(APIView):
    authentication_classes = [JWTAuthentication]

    @extend_schema(
        summary="사용자 로그아웃",
        description="사용자의 리프레시 토큰을 무효화합니다.",
        responses={200: OpenApiTypes.OBJECT}
    )
    def post(self, request):
        user = request.user
        user.refresh_token = ""
        user.save()
        return Response({"message": "Successfully logged out."}, status=status.HTTP_200_OK)

이 뷰는 JWT 인증을 사용하여 현재 로그인한 사용자를 식별하고, 사용자의 리프레시 토큰을 무효화합니다.

5. 비밀번호 재설정

비밀번호 재설정 기능은 RequestPasswordResetView와 SetNewPasswordView 클래스에서 구현됩니다.

class RequestPasswordResetView(APIView):
    permission_classes = [AllowAny]

    @extend_schema(
        summary="비밀번호 재설정 요청",
        description="사용자 이메일로 비밀번호 재설정 링크를 발송합니다.",
        # ... (생략)
    )
    def post(self, request):
        serializer = NewPasswordSerializer(data=request.data)
        if serializer.is_valid():
            email = serializer.validated_data['email']
            # ... (생략: 사용자 조회 및 이메일 발송 로직)
            return Response({'message': '비밀번호 재설정 이메일을 발송했습니다.'}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class SetNewPasswordView(APIView):
    permission_classes = [AllowAny]

    @extend_schema(
        summary="새 비밀번호 설정",
        description="비밀번호 재설정 링크를 통해 새 비밀번호를 설정합니다.",
        # ... (생략)
    )
    def post(self, request):
        serializer = SetNewPasswordSerializer(data=request.data)
        if serializer.is_valid():
            # ... (생략: 토큰 검증 및 비밀번호 재설정 로직)
            return Response({'message': '비밀번호가 성공적으로 재설정되었습니다.'}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

RequestPasswordResetView는 사용자 이메일로 비밀번호 재설정 링크를 발송하고, SetNewPasswordView는 재설정 링크를 통해 새 비밀번호를 설정합니다.

결론

이 Django REST Framework 기반의 인증 시스템은 현대적인 웹 애플리케이션에서 요구되는 대부분의 인증 기능을 포괄적으로 다루고 있습니다. JWT를 사용한 인증, 소셜 로그인 지원, 안전한 비밀번호 재설정 메커니즘 등을 통해 보안성과 사용자 편의성을 모두 고려했습니다.
이 시스템은 DRF의 APIView와 generics를 사용하여 구현되어 있어 확장성이 뛰어나며, drf-spectacular를 통한 API 문서화로 개발자 경험도 향상시켰습니다.
여러분의 프로젝트에 이러한 인증 시스템을 도입하면 안전하고 사용자 친화적인 로그인 경험을 제공할 수 있을 것입니다.

자세한 코드는 깃허브에~⭐️ [Project name: pollloop]

profile
아....평화롭게 오카네모찌 되고JOB다...

0개의 댓글