五、权限组件
权限组件=[权限类,权限类,权限类…]
执行所有权限类的has_permission方法,通过返回True,不通过返回False
默认情况下,所有的权限类都通过,才返回True
5.1简单应用权限组件
#ext.per
class MyPermission1(BasePermission):
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
token1=request.query_params.get('token1',None)
if token1=='111':
#如果token1==111,则代表有权限,返回True
return True
#否则返回False
return False
#views视图类
class OrderView(APIView):
# 调用权限组件
permission_classes = [ext.per.MyPermission1,]
def get(self, request):
return Response('order')
效果1:token1正确,有权限访问
效果2:token2错误,无权限访问
5.2自定义错误信息
class MyPermission1(BasePermission):
#自定义错误信息
message={'code':2001,'errMsg':'无权限访问该视图'}
def has_permission(self, request, view):
token1=request.query_params.get('token1',None)
if token1=='111':
return True
return False
效果:
5.3多个权限类
只有所有权限类都返回True,才能获取访问权限。任何一个类返回False,则不会执行该类后面的权限类。
from rest_framework.permissions import BasePermission
class MyPermission1(BasePermission):
#权限类1
message={'code':2001,'errMsg':'token1验证失败,无权访问'}
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
token1=request.query_params.get('token1',None)
if token1=='111':
return True
return False
class MyPermission2(BasePermission):
#权限类2
message={'code':2001,'errMsg':'token2验证失败,无权访问'}
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
token2=request.query_params.get('token2',None)
if token2=='222':
return True
return False
#视图类
class OrderView(APIView):
# 不需要认证
authentication_classes = []
# 调用多个权限组件
permission_classes = [ext.per.MyPermission1,ext.per.MyPermission2,]
def get(self, request):
return Response('order')
效果1(两个token都正确):
效果2(一个token正常,一个token错误)
5.4权限类的全局配置
#settings.py
REST_FRAMEWORK = {
"UNAUTHENTICATED_USER": None,
#权限类的全局配置,这里配置以后,所有的视图都需要进行权限认证。
'DEFAULT_PERMISSION_CLASSES':["ext.per.MyPermission1","ext.per.MyPermission2",],
}
5.5权限组件扩展
(重写check_permissions方法,让视图只要满足一个权限类,就能访问)
class OrderView(APIView):
# 不需要认证
authentication_classes = []
def check_permissions(self, request):
#重写check_permissions方法
no_permission=[]
for permission in self.get_permissions():
if permission.has_permission(request, self):
#只要有一个权限类满足,就正常返回
return
#如果有不满足的权限类,则将它加入列表
no_permission.append(permission)
#如果有不满足的权限类,则拒绝访问,并抛出错误信息
self.permission_denied(
request,
message=getattr(no_permission[0], 'message', None),
code=getattr(no_permission[0], 'code', None)
)
def get(self, request):
return Response('order')
(重写APIView方法,视图继承该类,让视图只要满足一个权限类,就能访问)
#ext.myapiview
class MyAPIView(APIView):
#重写APIView中的check_permissions方法,视图继承该类,让视图只要满足一个权限类,就能访问
def check_permissions(self, request):
#创建一个空列表,用于存入未通过认证的权限类
no_permission = []
if not self.get_permissions():
#如果权限类列表为空,表示无需认证权限,正常返回
return
for permission in self.get_permissions():
#遍历视图权限组中所中引用的所有权限类
if permission.has_permission(request, self):
#如果权限认证通过,则正常返回
return
#将未通过权限认证的权限类存入列表
no_permission.append(permission)
self.permission_denied(
#拒绝访问,并获取错误信息
request,
message=getattr(no_permission[-1], 'message', None),
code=getattr(no_permission[-1], 'code', None)
)
#视图类继承上面重写过的APIView类
class OrderView(MyAPIView):
# 不需要认证
authentication_classes = []
def get(self, request):
return Response('order')
5.6权限组件实例:
三个视图,login,user,order
login:用户登入,无需认证,也无需任何权限即可访问
user:用户信息,需要认证,需要管理员权限或主管权限或员工权限才能访问
order:订单信息,需要认证,需要管理员权限或主管权限才能访问
表结构:
class User(models.Model):
name=models.CharField(verbose_name='name',max_length=64)
password=models.CharField(verbose_name='password',max_length=64)
token=models.CharField(verbose_name='token',max_length=64,null=True,blank=True)
ROLE_CHOICES=(
(1,'管理员'),
(2,'部门主管'),
(3,'员工')
)
role=models.SmallIntegerField(verbose_name='角色',choices=ROLE_CHOICES,default=3)
重写APIView方法,视图继承该类,让视图只要满足一个权限类,就能访问
from rest_framework.views import APIView
class MyAPIView(APIView):
#重写APIView中的check_permissions方法,视图继承该类,让视图只要满足一个权限类,就能访问
def check_permissions(self, request):
#创建一个空列表,用于存入未通过认证的权限类
no_permission = []
for permission in self.get_permissions():
#遍历视图权限组中所中引用的所有权限类
if permission.has_permission(request, self):
#如果权限认证通过,则正常返回
return
#将未通过权限认证的权限类存入列表
no_permission.append(permission)
self.permission_denied(
#拒绝访问,并获取错误信息
request,
message=getattr(no_permission[-1], 'message', None),
code=getattr(no_permission[-1], 'code', None)
)
编写权限类
#ext.per
rom rest_framework.permissions import BasePermission
from app_api import models
class AdminPermission(BasePermission):
#管理员权限验证
message={'code':2001,'errMsg':'您不是管理员,无权访问'}
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
token=request.query_params.get('token',None)
if not token:
return False
user_obj=models.User.objects.filter(token=token).first()
if not user_obj:
return False
if user_obj.role==1:
#判断当前用户是否为管理员
return True
return False
class ManagePermission(BasePermission):
# 部门主管权限验证
message={'code':2001,'errMsg':'您不是部门主管,无权访问'}
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
token=request.query_params.get('token',None)
if not token:
return False
user_obj=models.User.objects.filter(token=token).first()
if not user_obj:
return False
if user_obj.role==2:
#判断当前用户是否为部门主管
return True
return False
class UserPermission(BasePermission):
# 员工权限验证
message={'code':2001,'errMsg':'您不是员工员,无权访问'}
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
token=request.query_params.get('token',None)
if not token:
return False
user_obj=models.User.objects.filter(token=token).first()
if not user_obj:
return False
if user_obj.role==3:
#判断当前用户是否为员工
return True
return False
视图类
class LoginView(MyAPIView):
#用户登入,不需要认证,不需要任何权限
authentication_classes = []
permission_classes=[]
def post(self,request):
name=request.data.get('name')
password=request.data.get('password')
print(name,password)
user_obj=models.User.objects.filter(name=name,password=password).first()
if not user_obj:
#用户名密码错误
return Response({'status':False,'errMsg':'用户名或密码错误'})
token=str(uuid.uuid4())
user_obj.token=token
user_obj.save()
return Response({'status':True,'token':token})
class UserView(MyAPIView):
#查看用户信息
#需要认证,需要管理员权限或主管权限或员工权限
permission_classes=[AdminPermission,ManagePermission,UserPermission,]
def get(self, request):
user_info=models.User.objects.all().values('name','token')
return Response(user_info)
class OrderView(MyAPIView):
# 需要认证
# 需要管理员权限或主管权限
permission_classes = [AdminPermission, ManagePermission,]
def get(self, request):
return Response('order')