DRF Tutorial

DRF Tutorial 4: Authentication & Permissions 3

waterclean101 2023. 2. 15. 13:28

object 수준의 권한

모든 스니펫을 누구나 볼 수 있도록 하되, 스니펫을 만든 사용자만 업데이트하거나 삭제할 수 있도록 하고 싶다면 이를 위해서는 사용자 지정 권한을 만들어야 한다.

snippets 앱에서 permissions.py라는 새 파일을 만들자.

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Write permissions are only allowed to the owner of the snippet.
        return obj.owner == request.user

 

이제 SnippetDetail 뷰 클래스에서 permission_classes 속성을 편집하여 스니펫 인스턴스 엔드포인트에 해당 사용자 지정 권한을 추가할 수 있다.

# snippets/views.py

from snippets.permissions import IsOwnerOrReadOnly


class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):

    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwenerOrReadOnly]

이제 브라우저를 다시 열면 스니펫을 만든 사용자와 동일한 사용자로 로그인한 경우에만 스니펫 인스턴스 엔드포인트에 '삭제' 및 '넣기' 작업이 표시된다.

 

API로 인증하기

이제 API에 대한 일련의 권한이 있으므로 스니펫을 편집하려면 API에 대한 요청을 인증해야 한다. 인증 클래스를 설정하지 않았으므로 현재 기본값인 SessionAuthentication과 BasicAuthentication이 적용된다.

웹 브라우저를 통해 API와 상호 작용할 때 로그인을 하면 브라우저 세션이 요청에 필요한 인증을 제공한다.

프로그래밍 방식으로 API와 상호 작용하는 경우 각 요청에 대해 명시적으로 인증 자격 증명을 제공해야 한다.

인증하지 않고 스니펫을 만들려고 하면 오류가 발생한다.

http POST http://127.0.0.1:8000/snippets/ code="print(123)"

{
    "detail": "Authentication credentials were not provided."
}

 

앞서 생성한 사용자 중 한 명의 사용자 이름과 비밀번호를 포함하면 요청을 성공적으로 수행할 수 있다.

http -a admin:password123 POST http://127.0.0.1:8000/snippets/ code="print(789)"

{
    "id": 1,
    "owner": "admin",
    "title": "foo",
    "code": "print(789)",
    "linenos": false,
    "language": "python",
    "style": "friendly"
}