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 |