장고

Django REST Framework permission class

content0474 2024. 12. 24. 14:16

DRF의 Permission Class는 API 요청에 대해 사용자가 접근 권한이 있는지를 판단

1. Permission Class란
Permission Class는 요청을 보낸 사용자가 특정 API 엔드포인트에 접근할 권한이 있는지 확인
API 요청을 허용하거나 거부할 수 있는 기본 도구이며 DRF는 기본적으로 몇 가지 권한 클래스를 제공한다.

이를 커스터마이징하여 다양한 권한 로직을 구현할 수 있음

2. DRF의 기본 권한 클래스
AllowAny

누구나 접근 가능
로그인 여부와 상관없이 모든 요청을 허용함

from rest_framework.permissions import AllowAny

class PublicAPIView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        return Response({"message": "Anyone can access this API"})

 

IsAuthenticated

로그인된 사용자만 접근 가능
로그인되지 않은 사용자는 401 Unauthorized 에러

from rest_framework.permissions import IsAuthenticated

class AuthenticatedAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"message": f"Hello, {request.user.username}"})



IsAdminUser
관리자인 사용자만 접근 가능
관리자가 아닌 사용자는 403 Forbidden 에러

from rest_framework.permissions import IsAdminUser

class AdminAPIView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        return Response({"message": "Welcome, Admin"})

 


3. 커스텀 권한 클래스 작성하기
기본 권한 클래스로 해결되지 않는 세부적인 권한 로직은 커스텀 클래스를 통해 구현할 수 있음

 

작성자만 수정/삭제 가능, 조회는 누구나 가능

from rest_framework.permissions import BasePermission

class IsAuthorOrReadOnly(BasePermission):
    """
    작성자만 수정/삭제 가능하고 조회는 모든 사용자 허용
    """
    def has_object_permission(self, request, view, obj):
        # 읽기 요청(GET, HEAD, OPTIONS)은 모두 허용
        if request.method in ['GET', 'HEAD', 'OPTIONS']:
            return True
        # 작성자만 쓰기 요청(PUT, DELETE)을 허용
        return obj.author == request.user


뷰에 적용

from rest_framework.permissions import IsAuthenticated
from .permissions import IsAuthorOrReadOnly

class ProductDetailAPIView(APIView):
    permission_classes = [IsAuthenticated, IsAuthorOrReadOnly]  # 로그인과 작성자 확인

    def get_object(self, pk):
        return get_object_or_404(Product, pk=pk)

    def get(self, request, pk):
        product = self.get_object(pk)
        serializer = ProductSerializer(product)
        return Response(serializer.data)

    def put(self, request, pk):
        product = self.get_object(pk)
        serializer = ProductSerializer(product, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)

    def delete(self, request, pk):
        product = self.get_object(pk)
        product.delete()
        return Response({"message": "Product deleted"})

 

4. 메서드별로 다른 권한 적용하기
메서드별로 서로 다른 권한 로직이 필요하다면 permission_classes를 클래스 단위로 설정하는 대신, get_permissions 메서드를 오버라이드하여 메서드별 권한을 적용할 수 있음

조회는 누구나 가능, 삭제는 로그인 사용자만 가능

from rest_framework.permissions import AllowAny, IsAuthenticated

class ProductAPIView(APIView):
    def get_permissions(self):
        if self.request.method == 'GET':
            return [AllowAny()]  # 조회는 누구나 가능
        elif self.request.method == 'DELETE':
            return [IsAuthenticated()]  # 삭제는 로그인 필요
        return super().get_permissions()

    def get(self, request):
        return Response({"message": "Anyone can view this"})

    def delete(self, request):
        return Response({"message": "Only logged-in users can delete"})

 


5. DRF 권한 클래스 사용 팁
권한 클래스 순서: 여러 권한 클래스를 설정한 경우, 첫 번째로 실패하는 권한이 반환하는 에러가 클라이언트에 표시됨
request.method 활용: 메서드(GET, POST 등)에 따라 권한을 다르게 설정할 수 있음
request.user와 obj.author 비교: 특정 객체의 작성자와 현재 요청한 사용자를 비교하여 권한을 제어 가능

 

6. Postman으로 테스트해보기
로그인 여부 확인: 401 Unauthorized 또는 200 OK 응답 확인
작성자 확인: 작성자가 아닌 사용자가 수정/삭제 요청을 보내면 403 Forbidden 응답
메서드별 권한 확인: GET은 모두 허용, DELETE는 로그인한 사용자만 가능

'장고' 카테고리의 다른 글

django aggregate  (2) 2024.12.27
django CustomUserModel  (0) 2024.12.26
django JWT  (0) 2024.12.23
Django Rest Framework  (1) 2024.12.19
RESTful API  (0) 2024.12.18