一、权限
权限可以限制用户对视图的访问和对具体数据对象的访问。
- 在执行视图的dispatch方法前,会先进行视图访问权限的判断
- 在通过get_object获取对象时,会进行模型对象访问权限的判断
源码分析
核心源码——>APIView——>dispatch——>initial——>self.check_permissions(request)
def check_permissions(self, request):
# 遍历权限对象列表得到一个个权限对象(权限器),进行权限认证
for permission in self.get_permissions():
# 权限类一定要有一个has_permission权限方法,用来做权限认证的
# 参数:权限对象self、请求对象request、视图类对象view
"""
has_permission(self, request, view):
"""
# 返回值:有权限返回True、无权限返回False
if not permission.has_permission(request, self):
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
权限使用
写一个类,继承BasePermission,重写has_permission,如果权限通过,就返回True,不通过就返回False。
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
def has_permission(self, request, view):
# 由于已经认证过了,request内就已经有了user对象了,当前用户
user = request.user # 当前登录用户
# 如果该字段用了choice,那么可以使用get_字段名_display(),取出choice后面的中文
print(user.get_user_type_display())
if user.user_type == 1: # 不是超级用户不能访问
return True
else:
return False
如何使用:
# 局部使用
from app01.app01_auth import UserPermission
class TestView(APIView):
authentication_classes = [TokenAuthentication] # 认证配置
permission_classes = [UserPermission] # 权限配置
# 全局使用
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":[
"app01.app01_auth.TokenAuthentication", # 全局认证配置
],
'DEFAULT_PERMISSION_CLASSES': [
'app01.app01_auth.UserPermission', # 全局权限配置
],
}
# 局部禁用 settings.py
class TestView(APIView):
permission_classes = [] # 局部禁用权限配置
内置权限
内置权限类
from rest_framework.permissions import AllowAny,IsAuthenticated,IsAdminUser,IsAuthenticatedOrReadOnly
- AllowAny 允许所有用户
- IsAuthenticated 仅通过认证的用户
- IsAdminUser 仅管理员用户
- IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。
如何使用
# 1 创建超级管理员 >>python manage.py createsuperuser
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication
class TestView(APIView):
authentication_classes=[SessionAuthentication,]
permission_classes = [IsAdminUser]
def get(self,request,*args,**kwargs):
return Response('这是测试数据,超级管理员可以看')
# 3 超级用户登录到admin,再访问test就有权限
# 4 正常的话,普通管理员,没有权限看(判断的是is_staff字段)
二、频率
可以用来减轻服务器压力,对接口访问的频率进行限制
内置频率限制
由于大部分需求使用内置的频率限制就已经可以了,所以主要看看内置的频率限制
限制未登录用户:AnonRateThrottle
也就是限制所有匿名未认证用户,使用IP区分用户。anon
设置频次
# 全局使用 settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '5/m', # 每分钟访问次数
}
}
# views.py
from rest_framework.views import APIView
class TestView(APIView):
def get(self, request):
return Response('我是未登录用户,每分钟只能访问5次')
# -------------------------------------------------------------------
# 局部使用
# 还是需要先在settings.py中配置访问次数
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'anon': '5/m',
}
}
# views.py
from rest_framework.throttling import AnonRateThrottle
from rest_framework.views import APIView
class TestView(APIView):
throttle_classes = [AnonRateThrottle] # 局部使用
def get(self, request):
return Response('我是未登录用户,每分钟只能访问5次')
限制登录用户:UserRateThrottle
需求:未登录用户1分钟访问5次,登录用户一分钟访问10次
对认证用户限制,使用User id 来区分,user
设置频次
但是这个有局限性,它只能是auth_user表,admin这套系统才能使用
# 全局使用 settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle', # 未登录用户
'rest_framework.throttling.UserRateThrottle' # 登录用户
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m', # 登录用户频率
'anon': '5/m', # 未登录用户频率
}
}
from rest_framework.views import APIView
class TestView(APIView):
def get(self, request):
return Response('未登录用户5次,登录之后10次')
IP频率限制:SimpledRateThrottle
限制用户对于每个视图的访问频率,使用IP限制
# 1、写一个类,继承SimpleRateThrottle,重写 get_cache_key
# app01_auth.py
from rest_framework.throttling import SimpleRateThrottle
class App01_Throttle(SimpleRateThrottle):
scope = 'luffy'
def get_cache_key(self, request, view):
# 返回什么源码中的key就是什么
return request.META.get('REMOTE_ADDR')
# 2、全局配置频率次数 settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'luffy': '5/m' # key要根据类中的scope对应
},
}
# 3、局部使用 views.py
from rest_framework.views import APIView
from app01.app01_auth import App01_Throttle
class TestView(APIView):
throttle_classes = [App01_Throttle] # 局部使用配置
def get(self, request):
return Response('IP限制每分钟访问5次')
# 全局使用需要在settings.py配置
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'app01.app01_auth.App01_Throttle', # 全局及配置
),
'DEFAULT_THROTTLE_RATES': {
'luffy': '5/m' # key要根据类中的scope对应
},
}