[DRF] custom permission 클래스로 서비스의 특정 기능에 사용자 접근 제한하기

0

Django Web dev

목록 보기
10/12

intro

여기, 서비스 유저가 업로드한 게시글을 조회할 수 있는 두 개의 API뷰가 있습니다.

from rest_framework import generics
from user_community.models import Post
  
class PostList(generics.ListAPIView):
  queryset = Post.postobjects.all()
  serializer_class = PostSerializer

class PostDetail(generics.RetrieveUpdateDestroyAPIView):
  queryset = Post.objects.all()
  serializer_class = PostSerializer

각각의 API VIEW에 접근할 수 있는 엔드포인트는 다음과 같습니다.

from django.urls import path
from .views import PostDetail, PostList

urlpatterns = [
  path('<int:pk>/', PostDetail.as_view(), name="each_posting_detail"),
  path('', PostList.as_view(), name="all_postings_list")
]

두 개의 게시물 조회 API뷰 PostListPostDetail 은 각각 다른 역할을 수행합니다.

ListAPIViewPostList 는 전체 게시물을 조회합니다.
RetrieveUpdateDestroyAPIViewPostDetail 은 게시물 객체 각각에 대하여 조회, 수정, 삭제 기능을 제공합니다.

게시물을 단순히 조회하도록 하는 것은 문제가 되지 않으나,
수정하거나 삭제하는 것은 권한 제한을 설정할 필요가 있습니다.

게시물의 수정 혹은 삭제 요청을 보낸 사용자가
게시물을 작성한 사용자와 같을 경우에만 수정 및 삭제하도록 만들어주면 좋을 것 같습니다.

저희는 DRF(Django Rest Framework) 커스텀 권한 클래스를 만들어보겠습니다.

how to make custom permission class

완성된 권한 클래스는 다음과 같습니다.

from rest_framework.permissions import BasePermission, SAFE_METHODS

class WritePostingPermission(BasePermission):
  message = "해당 게시물의 수정 또는 삭제 권한이 없습니다."
  
  def has_object_permission(self, request, view, obj):
    if request.method in SAFE_METHODS:
      return True
    
    return obj.author == request.user

모든 DRF custom permission class는 BasePermission 을 상속받아야 합니다.

이후, has_permission 혹은 has_object_permission 메소드를 구현해주어야 합니다.

저의 경우 게시물 객체 각각에 대한 권한을 부여하는 상황이니 후자를 선택하였습니다.

SAFE_METHODS 는 http request중 GET 등의 수정이나 삭제와는 관련이 없는,
단순 조회성 요청의 묶음입니다.

클라이언트 측에서 보낸 요청이 게시물의 수정이나 삭제에 대한 요청이 아닌 경우는,
권한을 True로 부여해주었습니다.

클라이언트의 요청이 DELETE, POST, PATCH, PUT등이라면,
조건문을 빠져나와 아래의 명령어를 수행합니다

return obj.author == request.user

obj는 게시물 객체 각각을 의미하며,
저의 경우 Post 객체의 스키마에 작성자 필드를 author 라는 이름으로 설정해두었습니다.

DB에 저장되어 있는 게시물의 작성자와, request를 보낸 user가 동일하면 True를 리턴해 권한을 부여받습니다.

how to apply custom permission to API VIEW

이제, 이 권한을 API VIEW에 적용해주어야 합니다.

class PostDetail(generics.RetrieveUpdateDestroyAPIView):
  permission_classes = [WritePostingPermission]
  queryset = Post.objects.all()
  serializer_class = PostSerializer

위와 같이, API뷰 내에서, permission_classes = [] 속에 권한 클래스를 지정해주면 됩니다.

이제, 해당 API뷰는 RetrieveUpdateDestroyAPIView 임에도, 게시물 작성자 이외에는 Update와 Destroy 기능이 비활성화 됩니다.

[참고자료]

[1] 유튜브 튜토리얼
https://www.youtube.com/watch?v=5AOn0BmSXyE&list=PLOLrQ9Pn6caw0PjVwymNc64NkUNbZlhFw&index=2
[2] DRF 공식문서
https://www.django-rest-framework.org/api-guide/permissions/

profile
웹 풀스택 개발자를 준비하고 있습니다. MERN스택을 수상하리만큼 사랑합니다.

0개의 댓글