[DRF] Permission

GreenBeanΒ·2021λ…„ 11μ›” 9일
0
post-thumbnail

Permission

Permission

DRF의 Permission System

  • ν˜„μž¬ μš”μ²­μ— λŒ€ν•œ ν—ˆμš©β€’κ±°λΆ€λ₯Ό κ²°μ •ν•˜λ©° APIView λ‹¨μœ„λ‘œ 지정이 κ°€λŠ₯
    • AllowAny (λ””ν΄νŠΈ μ „μ—­ μ„€μ •) : 인증 여뢀에 상관없이 λ·° ν˜ΈμΆœμ„ ν—ˆμš©
    • IsAuthenticated : 인증된 μš”μ²­μ— ν•œν•΄μ„œ λ·° 호좜 ν—ˆμš© (둜그인이 λ˜μ–΄μžˆμ–΄μ•Όλ§Œ μ ‘κ·Ό ν—ˆμš©)
    • IsAdminUser : Staff 인증 μš”μ²­μ— ν•œν•΄μ„œ λ·° 호좜 ν—ˆμš©
    • IsAuthenticatedOrReadOnly : 비인증 μš”μ²­μ—κ²ŒλŠ” 읽기 κΆŒν•œλ§Œ ν—ˆμš© (둜그인이 λ˜μ–΄ μžˆμ§€μ•Šμ•„λ„ μ‘°νšŒλŠ” κ°€λŠ₯)
    • DjangoModelPermissons : 인증된 μš”μ²­μ— ν•œν•˜μ—¬ λ·° 호좜 ν—ˆμš©, μΆ”κ°€λ‘œ μž₯κ³  λͺ¨λΈ λ‹¨μœ„ Permissions 체크
    • DjangoModelPermissionsOrAnonReadOnly : DjangoModelPermissions와 μœ μ‚¬, 비인증 μš”μ²­μ—κ²ŒλŠ” 읽기만 ν—ˆμš©
    • DjangoObjectPermissons : 비인증 μš”μ²­μ€ κ±°λΆ€, 인증된 μš”μ²­μ€ Object에 λŒ€ν•œ κΆŒν•œ 체크 μˆ˜ν–‰
# Permission
SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')

class AllowAny(BasePermission):
    def has_permission(self, request, view):
        return True
      
class IsAuthenticated(BasePermission):
    def has_permission(self, request, view):
        return request.user and request.user.is_authenticated
       
class IsAdminUser(BasePermission):
    def has_permission(self, request, view):
        return request.user and request.user.is_staff

class IsAuthorOrReadOnly(permissions.BasePermission):
    # 인증된 μœ μ €μ— ν•œν•΄, λͺ©λ‘ 쑰회/ν¬μŠ€νŒ… 등둝 ν—ˆμš©
    def has_permission(self, request, view):
        return request.user.is_authenticated
   
    # μž‘μ„±μžμ— ν•œν•΄ λ ˆμ½”λ“œμ— λŒ€ν•œ μˆ˜μ •/μ‚­μ œ ν—ˆμš©
    def has_object_permission(self, request, view, obj):
        # 쑰회 μš”μ²­(GET, HEAD, OPTIONS)에 λŒ€ν•΄ 인증여뢀 상관없이 ν—ˆμš©
        if request.method in permissions.SAFE_METHODS:
            return True
        # PUT, DELETE μš”μ²­μ— λŒ€ν•΄ μž‘μ„±μžμΌ 경우 μš”μ²­ ν—ˆμš©
        return obj.author == request.user

class IsAuthorUpdateOrReadOnly(permissions.BasePermission):
    def has_permission(self, request, view):
        return request.user.is_authenticated
   
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True
        if request.method == 'DELETE':
            return request.user.is_superuser # λ˜λŠ” .is_staff
        return obj.author == request.user
# Default μ „μ—­ μ„€μ • (settings.py)
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES' : [
         'rest_framework.permissions.IsAuthenticated',
    ]
}


# APIViewμ—μ„œμ˜ 지정
from rest_framework.permissions import IsAuthenticated

class ExampleView(APIView):
    permissions_classes = [IsAuthenticated]
   
    def get(self, request, format=None):
        content = {'status' : 'request was permitted'}
        return Response(content)


# @api_viewμ—μ„œμ˜ 지정
from rest_framework.decorators import permission_classes

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None)
    content = {'status' : 'request was permitted'}
    returnn Response(content)

Custom Permission

  • λͺ¨λ“  Permission ν΄λž˜μŠ€λŠ” λ‹€μŒ 2가지 ν•¨μˆ˜λ₯Ό μ„ νƒμ μœΌλ‘œ κ΅¬ν˜„
    • has_permission(request, view)
      • APIView μ ‘κ·Ό μ‹œ 체크
      • 거의 λͺ¨λ“  Permission ν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„λ˜λ©° λ‘œμ§μ— 따라 True/False λ°˜ν™˜
    • has_object_permission(request, view, obj)
      • APIView의 get_object ν•¨μˆ˜λ₯Ό 톡해 object νšλ“ μ‹œμ— 체크
      • 기쑴의 Mixin 상속 받을 경우RetrieveModelMixin, UpdateModelMixi, DestroyModelMixinμ—μ„œ get_object() μ‚¬μš©
      • DjangoObjectPermissionsμ—μ„œ κ΅¬ν˜„ν•˜λ©° λ‘œμ§μ— 따라 True/False λ°˜ν™˜
  • 기본적으둜 Custom Permission듀은 BasePermission을 상속받아 μž‘μ„±ν•˜κ²Œ 됨
    • Permission에 has_object_permission이 μ•„λ‹Œ has_permission은 ν•΄λ‹Ή μš”μ²­μ΄ λ“€μ–΄μ˜¬ λ•Œ 항상 싀행이 됨
    • has_object_permission이 λ“€μ–΄μ˜€κΈ° 전에도 has_permission을 μš°μ„  거친 ν›„ 싀행이 되고 APIViewμ—μ„œ μ—­μ‹œ μžλ™μœΌλ‘œ 싀행이 됨
    • ν•˜μ§€λ§Œ has_object_permission의 경우 λ³„λ„μ˜ 호좜 과정이 ν•„μš”
# Custom Permission
from django.contrib.auth import get_user_model
from rest_framework.permissions import BasePermission, SAFE_METHODS

class IsOwnerOnly(BasePermission):
    # μž‘μ„±μžλ§Œ μ ‘κ·Ό
    def has_object_permission(self, request, view, obj):
        if request.user.is_authenticated:
            # κ΄€λ¦¬μž
            if request.user.role == '10':
                return True
            elif hasattr(obj, 'profile'):
                return obj.profile.id == request.user.id
            elif obj.__class__ == get_user_model():
                return obj.id == request.user.id
            return False
        else:
            return False
profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 λŒ“κΈ€