REST 프레임 워크 권한 관리 소스 분석
입구에서 같은 인증 디스패치 () 추천 self.initial(request, *args, **kwargs)
진입initial()
def initial(self, request, *args, **kwargs):
# .......
# 用户认证
self.perform_authentication(request)
# 权限控制
self.check_permissions(request)
# ...
check_permissions()
권한 관리는 입구의 근원이다
# 权限管理
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
for permission in self.get_permissions():
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
그리고 사용자 개체 클래스 권한의 목록을 통과와 같은 인증, 및 호출 요소 목록 has_permission()
부울 값을 반환하는 방법을, True
기관의 대표, False
대표 권한이 없습니다.
def get_permissions(self):
return [permission() for permission in self.permission_classes]
당신은 호출 권한이없는 경우permission_denied()
def permission_denied(self, request, message=None):
if request.authenticators and not request.successful_authenticator:
raise exceptions.NotAuthenticated()
raise exceptions.PermissionDenied(detail=message)
REST의 인증 프레임 워크 (authentication_classes 어레이가 비어 있지 않은) 인증이 실패하면, 던져 NotAuthenticated 그렇지 던지는 것, 예외를 PermissionDenied 예외
class NotAuthenticated(APIException):
status_code = status.HTTP_401_UNAUTHORIZED
default_detail = _('Authentication credentials were not provided.')
default_code = 'not_authenticated'
401 오류로 이어질 것입니다 NotAuthenticated (사용자 자격 증명의 부족)
class PermissionDenied(APIException):
status_code = status.HTTP_403_FORBIDDEN
default_detail = _('You do not have permission to perform this action.')
default_code = 'permission_denied'
PermissionDenied 반환합니다 오류 403 (인증되지 않은 액세스 거부)
상기 permission_denied()
전달 클래스 매개 변수의 시간, 반사의 사용
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
이 클래스 객체에 권한을 찾을 것이다 message
속성을, 그것을 사용하는 찾을 수 없습니다 None
,이 매개 변수는 ApiException이 상속이, 그리고 ApiException이 생성자에 매개 변수가 예외가 세부에서 찾을 수 있음을 PermissionDenied 예외 나중에 사용됩니다 설명 및 그들의 권한 클래스의 메시지의 속성 정의는 인증 실패를 나타내는 후 변경 될 수있다
class APIException(Exception):
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
default_detail = _('A server error occurred.')
default_code = 'error'
def __init__(self, detail=None, code=None):
if detail is None:
detail = self.default_detail
if code is None:
code = self.default_code
# ...
예
# api/utils/Permission.py
from rest_framework.permissions import BasePermission
class CommonPermission(BasePermission):
"""
普通用户权限,作用于全局
"""
def has_permission(self, request, view):
print(request.user)
if request.user.user_type == 1:
return True
def has_object_permission(self, request, view, obj):
"""
一旦获得View权限,将获得所有object权限
:return: True
"""
return True
class VipPermission(BasePermission):
"""
VIP 用户权限
"""
message = '您首先要称为VIP才能访问'
def has_permission(self, request, view):
print(request.user)
if request.user.user_type == 2:
return True
def has_object_permission(self, request, view, obj):
return True
# api/view.py
from django.shortcuts import HttpResponse
from django.http import JsonResponse
from rest_framework.views import APIView
from api.utils.Permission import VipPermission
class LoginView(APIView):
authentication_classes = []
# 登录无需权限认证
permission_classes = []
def post(self, request, *args, **kwargs):
pass
@method_decorator(csrf_exempt, name='dispatch')
class ShopView(APIView):
def get(self, request, *args, **kwargs):
return HttpResponse(request.user.username)
def post(self, request, *args, **kwargs):
return HttpResponse('POST')
class VipIndexView(APIView):
"""
只授权给VIP用户查看
"""
permission_classes = [VipPermission]
def get(self, *args, **kwargs):
return JsonResponse("welcome VIP ", safe=False)
# RESTdemo.setting.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['api.utils.MyAuthentication.MyAuthentication'],
'UNAUTHENTICATED_USER': None,
'UNAUTHENTICATED_TOKEN': None,
'DEFAULT_PERMISSION_CLASSES': ['api.utils.Permission.CommonPermission']
}