유입되는 요청을 허용/거부하는 것을 결정하는 것이 아니라,
단순히 인증정보로 유저를 식별하는 것입니다.
1. 매 요청 시마다 APIView의 dispatch(request) 호출
2. APIView의 initial(request) 호출
3. APIView의 perform_authentication(request) 호출
4. request의 user 속성 호출 (rest_framework.request.Request 타입)
5. request의 _authenticate() 호출
from django.conf.urls import url
from django.contrib.auth import views
app_name = 'rest_framework'
urlpatterns = [
url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'),
name='login'),
url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
]
urlpatterns += [
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
개체(정보/코드 등)에 대한 접근을 허용하기 위해서, 인증/식별만으로는 충분하지 않습니다. 추가로 각 개체에 대한 허가가 필요합니다.
from rest_framework.permissions import IsAuthenticated
class ExampleView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
content = { 'status': 'request was permitted' }
return Response(content)
from rest_framework.decorators import permission_classes
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
content = { 'status': 'request was permitted' }
return Response(content)
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
dry-rest-permissions : 룰 기반 퍼미션 지원
https://github.com/dbkaplan/dry-rest-permissions
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 DjangoObjectPermissions(DjangoModelPermissions):
# ...
def has_object_permission(self, request, view, obj):
# authentication checks have already executed via has_permission
queryset = self._queryset(view)
model_cls = queryset.model
user = request.user
perms = self.get_required_object_permissions(request.method, model_cls)
if not user.has_perms(perms, obj):
if request.method in SAFE_METHODS:
raise Http404
read_perms = self.get_required_object_permissions('GET', model_cls)
if not user.has_perms(read_perms, obj):
raise Http404
return False
return True
from rest_framework import permissions
class IsAuthorOrReadonly(permissions.BasePermission):
# 인증된 유저에 한해, 목록조회/포스팅등록을 허용
def has_permission(self, request, view):
return request.user.is_authenticated
# 작성자에 한해, Record에 대한 수정/삭제 허용
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
from rest_framework import permissions
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 # 또는 request.user.is_staff
return obj.author == request.user