Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

Nonamed Develog

[TIL][240914] DRF Permission Class 본문

WHAT I LEARN/TIL

[TIL][240914] DRF Permission Class

노네임드개발자 2024. 9. 14. 01:41

오늘은 Django REST Framework(DRF)에서 사용되는 Permission Class에 대해 학습했다. DRF에서 API 요청에 대한 권한을 설정할 때 request.user를 통해 간단히 접근할 수 있지만, 그럼에도 불구하고 Permission Class를 사용하는 이유가 무엇인지에 대해 고민했다.

1. request.user로 권한 설정

Django는 기본적으로 request.user를 통해 현재 요청을 보낸 사용자의 정보를 제공한다. 이 정보를 활용하면, 간단한 권한 체크가 가능하다. 예를 들어, 로그인된 사용자만 접근 가능하게 하려면 뷰에서 다음과 같은 방식으로 처리할 수 있다.

def get(self, request):
    if not request.user.is_authenticated:
        return Response({"detail": "Authentication required"}, status=401)

 

이처럼 request.user를 직접 활용하여 권한을 제어하는 것은 쉽고 직관적이다.

2. Permission Class를 사용하는 이유

그렇다면, DRF에서 이미 request.user로 권한을 제어할 수 있음에도 왜 Permission Class를 추가로 사용하는 걸까?

a. 코드 재사용성과 가독성

권한 검사를 각 뷰에서 request.user를 통해 직접 처리하게 되면, 같은 검사가 여러 뷰에 반복될 수 있다. Permission Class를 사용하면 권한 검사를 하나의 클래스에서 정의하고 여러 뷰에서 재사용할 수 있어 코드의 중복을 줄이고, 관리가 쉬워진다.

from rest_framework.permissions import BasePermission

class IsAdminUser(BasePermission):
    def has_permission(self, request, view):
        return request.user and request.user.is_staff

 

이렇게 정의한 Permission Class는 다양한 뷰에서 적용 가능하며, 가독성 측면에서도 권한과 관련된 로직을 분리하여 뷰 코드를 간결하게 유지할 수 있다.

b. 역할과 목적의 명확화

request.user는 기본적으로 사용자의 인증 정보를 제공하는 역할을 한다. 하지만 권한 관리는 이와 별개로 더 세밀한 통제가 필요한 경우가 많다. 예를 들어, 사용자가 관리자인지 여부, 특정 리소스에 대한 접근 권한이 있는지 등을 확인하려면 더 복잡한 로직이 필요할 수 있다. Permission Class는 이러한 "권한"에 대한 논리를 명확하게 분리해 관리할 수 있게 해준다.

c. DRF의 공식적인 구조 활용

DRF는 권한 설정을 위한 공식적인 구조로 Permission Class를 제공하며, 이를 사용하면 DRF의 다른 기능과 통합하여 쉽게 관리할 수 있다. 예를 들어, permission_classes 속성을 통해 뷰별로 간단히 권한을 설정할 수 있다.

from rest_framework.permissions import IsAuthenticated

class MyView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        # 인증된 사용자만 이 뷰에 접근 가능
        pass

d. 다양한 권한 조합 가능

Permission Class는 여러 권한 클래스를 조합하여 사용할 수 있다. 예를 들어, 사용자가 로그인했는지 여부와 관리자 권한을 동시에 체크할 때 다음과 같이 설정할 수 있다:

from rest_framework.permissions import IsAuthenticated, IsAdminUser

class MyAdminView(APIView):
    permission_classes = [IsAuthenticated, IsAdminUser]

    def get(self, request):
        # 인증된 관리자만 이 뷰에 접근 가능
        pass

3. 자주 쓰이는 Permission Class

DRF에서 자주 사용되는 Permission Class는 다음과 같다:

1. IsAuthenticated

  • 로그인한 사용자만 접근을 허용한다.
  • 익명 사용자(비로그인 상태)는 접근할 수 없으며, 인증이 필요하다.
  • 보통 인증이 필요한 API에 자주 사용된다.
from rest_framework.permissions import IsAuthenticated

class MyView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        # 인증된 사용자만 이 뷰에 접근 가능
        pass

2. IsAdminUser

  • 관리자인 사용자(즉, is_staff=True인 사용자)만 접근 가능하다.
  • 관리자 페이지나 특정 권한을 가진 사용자만 접근할 수 있도록 할 때 사용된다.
from rest_framework.permissions import IsAdminUser

class AdminView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        # 관리자만 이 뷰에 접근 가능
        pass

3. AllowAny

  • 모든 사용자에게 접근을 허용한다.
  • 일반적으로 로그인 여부와 상관없이 접근 가능한 API에 사용되며, 기본적으로 사용자가 인증되지 않아도 접근 가능한 페이지에서 사용된다.
from rest_framework.permissions import AllowAny

class PublicView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        # 누구나 접근 가능
        pass

4. IsAuthenticatedOrReadOnly

  • 인증된 사용자에게는 모든 작업을 허용하지만, 인증되지 않은 사용자에게는 읽기 작업(GET 요청)만 허용한다.
  • 일반적인 게시글 목록 조회는 누구나 가능하지만, 게시글 작성은 로그인된 사용자만 할 수 있도록 할 때 유용하다.
from rest_framework.permissions import IsAuthenticatedOrReadOnly

class PostViewSet(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticatedOrReadOnly]

    def perform_create(self, serializer):
        # 인증된 사용자만 글을 작성할 수 있다
        serializer.save(author=self.request.user)

5. DjangoModelPermissions

  • Django 모델에서 정의된 권한을 기반으로 접근을 허용한다.
  • 기본적으로 조회, 추가, 변경, 삭제 권한이 부여된 사용자만 해당 작업을 수행할 수 있다.
from rest_framework.permissions import DjangoModelPermissions

class RestrictedModelViewSet(viewsets.ModelViewSet):
    permission_classes = [DjangoModelPermissions]

4. 결론

비록 request.user를 통해 간단한 권한 체크를 할 수 있지만, DRF의 Permission Class는 코드의 재사용성, 관리의 용이성, 그리고 역할의 명확성을 고려했을 때 매우 유용하다. Permission Class를 사용함으로써 권한 관련 로직을 중앙화하고, DRF의 기능을 더 효과적으로 활용할 수 있다. 또한, DRF에서 제공하는 다양한 Permission Class를 적절히 활용하면 훨씬 더 유연하고 강력한 권한 관리를 할 수 있다.