DRF - permissions

Nam Eun-Ji·2021년 11월 22일
0

Django REST Framework

목록 보기
1/4

DRF에서 제공하는 permissions

  1. AllowAny: 인증/비인증 모두 허용 (default)
  2. IsAuthenticated: 인증된 요청에 대해서만 view 호출
  3. IsAdminUser: Staff User에 대해서만 요청 허용 (User.is_staff가 True여야 함)
  4. IsAuthenticatedOrReadOnly: 비인증 요청에 대해서는 읽기만 허용
  5. DjangoModelPermissions: 사용자 인증과 관련 모델 권한이 할당된 경우 허용 (django.contrib.auth 모델 permission과 관련 있음)
  6. DjangoModelPermissionOrAnonReadonly: DjangoModelPermission과 유사, 비인증 요청에 대해서는 읽기만 허용
  7. DjangoObjectPermissions: 모델에 대한 객체 별로 권한이 할당된 경우 허용
  8. Custom Permission: 개발자가 custom 하게 permission을 만들어서 사용할 수도 있음




permission globally setting

  • permission을 설정하지 않으면 누구나 접근할 수 있다. 아래는 기본적으로 설정되어 있는 코드.
'DEFAULT_PERMISSION_CLASSES': [
    'rest_framework.permissions.AllowAny',
]
  • 인증된 사용자만 접근하게 하려면,
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',
    ]
}
  • 하지만 보통 서비스에선 특정 뷰 혹은 클래스 더 작은 단위로 쪼개서 인증을 요한다.




No custom + locally

  • Views.py에서 permissions 모듈 임포트
  • permission_classes에 사용할 permissions 클래스 명시
from rest_framework import permissions

class EbookListCreateAPIView(generics.ListCreateAPIView):
    queryset = Ebook.objects.all()
    serializer_class = EbookSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]




Custom permission

  • request에 액세스 권한이 부여되면 메서드는 True를 반환하고, 아니면 False를 반환해야 한다.
  • request가 read인지, write인지 테스트해야하는 경우 'GET', 'OPTIONS' 및 'HEAD'를 포함하는 tuple형태의 'SAFE_METHODS'와 request method를 확인해야한다.

has_permission(request, view)

  • APIView 접근시, 체크.
  • 거의 모든 Permission 클래스에서 구현되며 로직에 따라 True/False 반환
# permissions.py
# - api 폴더 내에 permissions.py를 생성, 필요한 클래스를 직접 작성하여 사용
# - `IsAdminUserOrReadOnly`라는 커스터마이즈된 permission 클래스를 만들기 위해 `IsAdminUser`를 상속하여 코드를 작성
from rest_framework import permissions

class IsAdminUserOrReadOnly(permissions.IsAdminUser):
    """
    해당 유저가 admin이면 CRUD 허용해주고,
    request.method가 ('GET', 'HEAD', 'OPTIONS') 중 하나이면 READ를 허용해줌.
    """
    def has_permission(self, request, view):
        is_admin = super().has_permission(request, view)
        return request.method in permissions.SAFE_METHODS or is_admin


# views.py
# - customized된 permissions 클래스를 임포트

class EbookListCreateAPIView(generics.ListCreateAPIView):
    queryset = Ebook.objects.all()
    serializer_class = EbookSerializer
    permission_classes = [IsAdminUserOrReadOnly]

has_object_permission(request, view, obj)

  • APIView의 get_object 함수를 통해 object 획득 시에 체크.
  • 브라우저를 통한 API 접근에서 CREATE/UPDATE Form 노출 시 체크
    DjangoObjectPermissions에서 구현하며 로직에 따라 True/False 반환
# permissions.py
class IsReviewAuthorOrReadOnly(permissions.BasePermission):
    """
    request.method가 ('GET', 'HEAD', 'OPTIONS') 중 하나이면 READ를 허용해주고,
    그 외의 메소드일 경우 해당 리뷰를 쓴 유저인 경우에만 CRUD를 허용해준다.
    """
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True

        return obj.review_author == request.user

# views.py
class ReviewDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer
    permission_classes = [IsReviewAuthorOrReadOnly]
profile
한 줄 소개가 자연스러워지는 그날까지

0개의 댓글