自定义权限类使用示例
from rest_framework.permissions import BasePermission #权限基类
class MyPermission(BasePermission):
'''自定义权限类'''
message="没有访问权限"
def has_permission(self,request,view):
if 条件:#无权限返回False,有权限返回Ture
return False
return True
class Eg(APIView):
authentication_classes = [MyAuthenticate,] #使用自定义认证类
permission_classes = [MyPermission,] #局部使用自定义权限类
def get(self,request,*args,**kwargs):
print(request.user)
return HttpResponse("GET")
上面是局部用,全局用法也和认证一样
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication', #使用的全局认证类
),
'DEFAULT_PERMISSION_CLASSES': (
#'rest_framework.permissions.AllowAny',
'rest_framework.permissions.IsAuthenticated', #使用的全局权限类
#所有都要经过登录认证,不然什么权限都没有
#这是全局的。登录之后的局部权限自定义
),
}
权限源码解析
全面部分看认证部分
我们直接从self.initial
看
def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
首先看到self.perform_authentication(request)
就是执行认证的部分。
那么self.check_permissions(request)
就是权限执行的部分
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)
)
其中self.get_permissions()
就是权限对象列表,局部和全局配置方法和认证一样。
循环执行列表对象的has_permission
方法,(所以在自定义时要写上这个方法)
注:has_permission
方法中if中的条件部分,一般是用request.user做判断(因为认证一般会返回用户对象)
- 如果
has_permission
返回值为true,结束本次的权限类,走下一个权限类。如果所有的权限类返回值都为true,则权限通过。进行下面的节流 - 如果
has_permission
的返回值为false,则执行permission_denied
方法。
def permission_denied(self, request, message=None):
"""
If request is not permitted, determine what kind of exception to raise.
"""
if request.authenticators and not request.successful_authenticator:
raise exceptions.NotAuthenticated()
raise exceptions.PermissionDenied(detail=message)
则抛出权限异常,被外层捕捉,返回给客服端
{
"msg": "Authentication credentials were not provided."
}
其中message可自定义,见自定义权限类示例