TIL 240429

hyeo71·2024년 4월 29일
0

2024 내배캠 AI 트랙

목록 보기
84/108

DRF Custom Permission

product api를 구현 중 수정, 삭제는 기존의 permissions.isauthenticated를 사용하면 로그인한 사용자가 다른 사용자가 만든 product를 수정, 삭제를 하기 때문에 Custom Permission을 구현해야했다.

공식문서를 보고 구현을 했다.

#products/permissions.py

class IsOwnerOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True

        return obj.author == request.user

하지만 postman으로 확인을 하니 로그인한 사용자는 모두 수정, 삭제가 되며 적용이 안되는 것을 확인했다. 이를 해결하기 위해 구글링을 하던 중 나와 같은 현상을 겪고 이를 해결한 블로그를 발견했다.

참고한 블로그

공식문서

Note that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself. You can do so by calling self.check_object_permissions(request, obj) from the view once you have the object instance. This call will raise an appropriate APIException if any object-level permission checks fail, and will otherwise simply return.

has_permission 메서드와 달리, has_object_permission 메서드는 인스턴스 레벨에서 유효성을 검사한다.

그런데 인스턴스 레벨의 검사가 작동하려면, view의 코드가 명시적으로 self.check_object_permissions 메서드를 호출해야 한다고 한다. (제네릭 뷰에서는 따로 호출하지 않아도 자동으로 작동한다.)

그런데 해당 메서드는 APIView의 내장 메서드이기 때문에, 함수 기반 뷰에서는 호출할 수가 없다. 내부 로직 자체를 직접 구현하는 방법도 있지만, 이는 매우 어려울 것이다. 결국 해당 부분을 클래스 기반 뷰로 수정하고, 클래스 내의 get_object 메서드에서 check_object_permissions을 호출하여 검사하는 방식으로 코드를 수정했다.

이를 보고 문제를 해결했다.

# products/views.py

	def get_object(self, productId):
        product=get_object_or_404(Product, pk=productId)
        self.check_object_permissions(self.request, product)
        return product

0개의 댓글