DRF权限组件代码实现

权限类和认证类同样的逻辑,同样的方式,只是执行权限的方法名与执行认证的方法名不一样而已,名为has_permission,并且需要将当前的视图类传递给该方法。

创建自定义权限类

自定义类位置:app.untils.permission.UserPermission

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 引入restframework权限基类,可不引入
from rest_framework.permissions import BasePermission

class UserPermission(BaseException):
# 定义无权限访问提示语
message = '你没有该权限访问'
# 判断用户权限
def has_permission(self, request, view):
# 获取用户等级,并判是否等级大2,则代表有权限,否则无权限
if request.user.level>2:
return True
else:
return None

视图类中指定接口判断权限

1
2
3
4
5
6
7
8
9
10
11
12
# 引入自定义权限类
from app.untils.permission import UserPermission

# 书籍列表
class BooksView(ModelViewSet):
# 设置queryset和自定义序列化类
queryset = BookModel.objects.all()
serializer_class = BookSerialize
# 需要认证的类
authentication_classes = [UserAuth]
# 需要判断权限的类测试
permission_classes = [UserPermission]

使用postman测试改接口

测试接口地址:127.0.0.1:8000/books?token=008b3809097c42d4a0ba9bf94a5532e6

如果该token不正确,则认证类就直接先拦截下来了,根本走不到权限类。如果token值正确,且对应的用户level小于3,接口响应内容为

1
2
3
{
"detail": "你没有该权限访问"
}

反之显示书籍列表

views.py所有代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# DRF token认证组件
from django.http import JsonResponse

from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
# from rest_framework.exceptions import APIException

# 引入用户模型
from app.models import User as UserModel
from app.models import UserToken as UserTokenModel
from app.models import Book as BookModel
from app.untils import get_token
# 引入自定义序列化类
from app.api_serialize import BookSerialize
# 引入自定义认证类
from app.untils.authentication import UserAuth
# 引入自定义权限类
from app.untils.permission import UserPermission
# 用户登录
class UserView(APIView):
def post(self, request):
# 定义一个返回字典
response = dict()
# 定义一个接收数据字典
recev_data = {'username', 'password'}
# 判断用户发送的post数据是否是要接受数据的子集,即用户发送的字段是否符合包含要接受的字段
if recev_data.issubset(set(request.data)):
# 接收用户发送符合要求的数据
userInfo = dict()
for item in recev_data:
userInfo[item] = request.data.get(item)
# 查询是否有该用户
user_obj = UserModel.objects.filter(**userInfo).first()
# 判断用户名密码是否正确
if user_obj:
# 生成access_token
access_token = get_token.generater_token()
# 将生成的access_token写入数据表
UserTokenModel.objects.update_or_create(user=user_obj, defaults={
'token':access_token
})
response['status_code'] = 200
response['status_message'] = '恭喜你,登录成功'
response['access_token'] = access_token
response['user_role'] = user_obj.get_level_display()
else:
response['status_code'] = 201
response['status_message'] = '用户名或密码错误'
return JsonResponse(response)

# 书籍列表
class BooksView(ModelViewSet):
# 设置queryset和自定义序列化类
queryset = BookModel.objects.all()
serializer_class = BookSerialize
# 需要认证的类
authentication_classes = [UserAuth]
# 需要判断权限的类测试
permission_classes = [UserPermission]