ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [개념 정리] Custom Permission 구현과 has_permission과 has_object_permission의 차이
    django 2022. 3. 24. 14:14

     # Custom Permission

     : 종종 REST framework에서 view class에 permission_classes를 이용하여 permission을 관리할 때, 기존에 있는 AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly 등으로는 구현할 수 없어 Custom Permission을 직접 정의하여 설정해줘야 할 때가 있다. 예를 들어 위의 4가지 permission class로는 로그인한 유저가 다른 유저의 object id를 통해 이를 마음대로 수정하거나 삭제하는 행위를 막을 수 없다. 따라서 이 경우 유저가 object에 접근하려 할 때, 해당 object의 주인과 요청을 보내는 유저가 동일한지 확인하는 로직이 필요한데, view에서 해당 method에 이를 validate 하는 코드를 직접 구현해도 되고, 별도의 Custom Permission을 만들어도 된다. Custom Permission은 보통 별도의 permissions.py에 BasePermission을 상속하여 .has_permission(self, request, view) 혹은 .has_object_permission(self, request, view, obj)을 override 한다. 다음은 위 예시에 대한 Custom Permission이다. 하나씩 살펴보자.


    from rest_framework import permissions
    
    class IsOwnerOrCreateReadOnly(permissions.BasePermission):
        """
        Only object's owner can update / delete object.
        Not owner but Authenticated user can create / get objects.  
        """
        message = '권한이 없습니다.'
        def has_permission(self, request, view):
        	return request.user and request.user.is_authenticated
        def has_object_permission(self, request, view, obj):
            if request.method in permissions.SAFE_METHODS:
                return True
            return obj.user == request.user

     

    - message는 permission check에 통과하지 못했을 때 보여지는 내용이다. 이 attribute가 구현되지 않을 경우 PermissionDenied의 default_detail로 설정된다.

     

    - has_permission과 has_object_permission는 permission custom시 구현해야 하는 부분으로 둘 중 하나 혹은 둘 다 구현해도 된다. 둘의 차이점에 대해서는 밑에서 설명할 것이다.

     

    - SAFE_METHODS는 'GET', 'OPTIONS', 'HEAD' 등을 의미한다.


     # has_permission vs has_object_permission

    - has_permission : 해당 HTTP request에 대한 global한 승인

    - has_object_permission : 특정 객체 (object)에 대한 승인 

     

        정의가 와닿지 않는다면 비유를 한번 해보자. has_permission은 친구의 허락을 받고 친구 집에 들어가는 것이고, has_object_permission은 친구의 허락을 받고 친구 집의 물건들을 구경하고 갖고 놀 수 있는 것이다. 당연히 친구 집의 물건들을 갖고 놀기 위해서는 친구 집에 우선 들어갈 수 있어야 한다. has_object_permission 역시 has_permission이 먼저 호출된 다음에 호출된다. has_permission을 통과하지 못하면 has_object_permission 역시 호출되지 않는다.

     

    위 예시 코드를 통해 인증된 유저만 request를 허용했고, request 중 object에 접근할 수 있는 method는 object를 건드리지 않고 단순 조회만 하는 SAFE_METHOD인 GET만 허용했다. 

     

    이렇게 Custom permission을 만들었다면, Class Based View는 permission_classes = [<permission 이름>], Function Based View는 @permission_classes([<permission 이름>])으로 적용해주거나, settings.py에서 'DEFAULT_PERMISSION_CLASSES'의 value로 설정해주자. 자세한 건 공식문서를 참고 !

Designed by Tistory.