Permissions
Permissions를 가져오는 법
from rest_framework.permissions import <Permission 이름>
Permissions를 통해 View에 필요한 권한을 설정할 수 있다.
REST 프레임워크에는 특정 View에 액세스할 수 있는 사용자를
제한할 수 있는 여러 Permission class가 포함되어 있다.
DRF에서 기본적으로 제공하는 Permission들은 다음과 같다.
- AllowAny
- IsAuthenticated
- IsAdminUser
- IsAuthenticatedOrReadOnly
- DjangoModelPermissions
- DjangoModelPermissionsOrAnonReadOnly
- DjangoObjectPermissions
사용 예시)
class MoongTangView(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
...
Custom Permissions
Custom Permissions를 생성하려면, BasePermission을 상속 후
다음 두 가지 중 하나 이상을 오버라이딩 해야한다.
- .has_permission(self, request, view)
- .has_object_permission(self, request, view, obj)
각각의 메소드는 요청에 액세스 권한을 부여해야 하는 경우 True를 반환,
그렇지 않으면 False를 반환하도록 하면 된다.
request가 READ 인지 WRITE 작업인지 테스트해야 하는 경우,
request.method를 상수 SAFE_MODES에 대해 확인해야 한다.
if request.method in permissions.SAFE_METHODS:
# read-only 요청(GET, OPTIONS, HEAD)에 대한 권한 확인
else:
# write 요청(POST, UPDATE, DELETE ...)에 대한 권한 확인
객체 권한을 검사하는 has_object_permission 메서드는
view 단위의 has_permission 검사가 이미 통과된 경우에만 호출된다.
또한 객체에 대한 권한을 검사하려면 View에서
.check_object_permissions(request, obj)
를 명시적으로 호출해야 한다.
generic views를 사용하는 경우 이는 기본적으로 처리된다.
(FBV는 개체 권한을 명시적으로 확인해야 하므로 실패 시 PermissionDenied)
Custom permissions은 테스트가 실패할 경우 PermissionDenied
예외와 관련된 오류 메시지를 변경하려면 custom permission에서 직접 지정해주면 된다.
지정하지 않았다면 PermissionDenied의 default_detail 특성이 사용
커스텀 예시)
오브젝트의 Owner이거나 ReadOnly인지 확인하는 커스텀 퍼미션.
당연하게도 객체와 유저는 관계가 있어야 한다.
아래 예시에서는 객체의 owner(user를 FK로 사용)로 유저를 판별
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
Admin이거나 ReadOnly인지 확인하는 커스텀 퍼미션
class IsAdminUserOrReadOnly(IsAdminUser):
def has_permission(self, request, view):
is_admin = super().has_permission(request, view)
return request.method in SAFE_METHODS or is_admin
Permission의 인증과 권한에 따른 HTTP Response
요청 OK, 권한 X
> HTTP 403 Forbidden 반환
요청 X, 최우선 인증 클래스에서 WWW-Authenticate 헤더를 사용 X
> HTTP 403 Forbidden 반환
요청 X, 최우선 인증 클래스에서 WWW-Authenticate 헤더를 사용 O
> HTTP 401 Unauthorized 반환
*참고
PermissionDenied의 Exception의 경우
http 상태코드(status_code),
에러코드(default_code),
에러 메시지(default_detail)로 이루어져있고,
이 역시 오버라이딩해서 사용 가능하다.
메시지와 코드 변경 예시)
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
message = 'Adding customers not allowed.'
code = 'CustomException'
def has_permission(self, request, view):
...
공식문서에는 예시처럼 message와 code를 통해서 작성해주는 방법이 있고,
default_code와 default_detail을 작성해줘도 된다고 적혀있다.
'Python > Django' 카테고리의 다른 글
[DRF] permission_classes = [A, B]와 [A & B]의 차이 (5) | 2023.06.21 |
---|---|
[Django] bulk_create (0) | 2023.06.16 |
[DRF] GenericAPIView와 Mixins (0) | 2023.06.07 |
[DRF] ModelSerializer와 CreateModelMixin 사용하기 (0) | 2023.06.06 |
[DRF] Serializer - depth, repr() (0) | 2023.06.06 |
댓글