drf之认证、权限、频率
1、认证
1.1 认证类的构建
新建一个自定义类,该类继承rest_framework.authentication中的BaseAuthentication
类,重写其中的authenticate
方法。将需要的认证逻辑写在里面。当认证通过是需要返回两个值,其中一个值最终给了Request
的user
。认证失败时,抛出异常:APIException
或者AuthenticationFailed
。其中该方法必须重写,如不重写其中没有认证逻辑,则直接抛出异常。
为方便管理,认证类写在新建的.py文件中。
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01 import models # 自定义模型
class MyAuthentication(BaseAuthentication):
def authenticate(self, request):
# 从META中取出请求中带的登录接口返回给前端的token
token = request.META.get('HTTP_TOKEN')
if token:
user_token = models.Token.objects.filter(Token=token).first()
if user_token:
return user_token.user, token
else:
raise AuthenticationFailed('认证失败')
else:
raise AuthenticationFailed('需要认证')
1.2 认证类的使用
- 全局使用:
在settings.py 中的
REST_FRAMEWORK
中添加DEFAULT_AUTHENTICATION_CLASSES
。如下所示:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.user_auth.MyAuthentication",] #可以有多个
}
- 局部使用:
在需要进行认证的视图类中添加
authentication_classes
。如下所示:
class BookAPIView(ModelViewSet):
authentication_classes = [MyAuthentication, ]
'''
可以是元组也可以是列表,里面可以有多个值,当有多个值的时候,从左到右依次认证。其中第一个认证不能有两个返回值,否则只能进行第一个认证。有多个认证时,需要将返回值为两个的放到最后
'''
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
- 局部禁用:
在需要禁用认证的视图类中,将
authentication_classes
设置为空。如下所示: class LoginView(APIView): authentication_classes = () def post(self, request): ...
2 权限
2.1 权限类的构建
新建一个类,继承rest_framework.permissions中的BasePermission,并重写其中的has_permission方法,其中是验证权限的逻辑。如果验证通过则return True,如果验证失败则返回False。
示例:
from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
def has_permission(self, request, view):
'''
在进行权限验证之前,drf会首先对请求进行认证操作,当其认证通过时之后才会进行权限认证。此时request中已经包含了登录用户的信息,我们可以将其取出进行权限验证。
'''
user=request.user # 当前登录用户
if user.user_type==1:
return True
else:
return False
2.2 权限类的使用
同认证类相似,权限类也有全局使用,局部使用和局部禁用。
其中全局使用的配置是:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",],
'DEFAULT_PERMISSION_CLASSES': [
'app01.app_auth.UserPermission',
],
}
局部使用则是在相应的视图类中添加 permission_classes 属性。比如:
class TestView(APIView):
permission_classes = [app_auth.UserPermission,]
pass
将视图类中的permission_classes 设置为空即可在全局配置了权限的情况下实现,权限的局部禁用。
2.3 drf内置的权限类
drf为我们内置了几个权限类,当我们的的需求类似时,可以直接使用其内置的权限类,避免代码冗余。这几个权限类依次是
-
IsAdminUser
校验Django自带用户表中的is_staff字段,判断认证用户是否是管理员(注意:其判断的不是is_superuser字段,而是is_staff,即该用户是职员状态是就可以通过权限认证)。 -
IsAuthenticated
所有通过认证的请求都可以通过权限验证,都会返回True。 -
IsAuthenticatedOrReadOnly
当请求通过认证或者请求是'GET
', 'HEAD
', 'OPTIONS
'方式时,可以通过权限验证。 -
AllowAny
所有请求都可以通过权限校验,当你没有配置权限类的时候就会默认使用AllowAny 。
权限的校验依靠于认证类返回的结果,所以我们使用时必须要搭配相应的认证类使用。
3 频率
3.1 频率类的构建
新建一个频率类。继承rest_framework.throttling中的SimpleRateThrottle,重写get_cache_key 方法。其中可以取出请求中的ip,user,设备信息等,将选用的频率限制标准返回即可。即返回ip即按照ip限制访问频率,返回用户名或用户对象即根据用户进行限制。
示例:
from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
scope='ip'
'''
其中scope属性为配置中访问频率设置的关键字,必须在频率类中对该属性进行赋值,且与sttings中要一一对应。
'''
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR')
3.2 频率类的使用
- 全局使用 REST_FRAMEWORK={ 'DEFAULT_THROTTLE_CLASSES': ( 'utils.throttling.MyThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'ip': '3/m' # key要跟类中的scop对应 格式可为'3/m','3/h','3/d'等 }, 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) }
- 局部使用:在相应的类中添加
throttle_classes
属性即可。示例: class TestView(APIView): throttle_classes = [MyThrottle,] pass - 将视图类中的
throttle_classes
设置为空即可在全局配置了频率限制的情况下实现,频率限制的局部禁用。
3.3 df内置的频率限制类
drf为我们内置了几个权限类,依次为:
-
UserRateThrottle
:对登录用户进行频率限制。如果登录用户经过了认证,则限制的依据是该用户的user_id,否则就是该请求的ip地址。setting中的scope为user
。 -
AnonRateThrottle
:对未登录用户进行频率限制,限制依据是用户请求中的ip地址,setting中的scope为anon
。
4 过滤与排序
4.1 过滤
- 安装第三方插件:
pip3 install django-filter
- 在Django中注册app
- 全局配置或者局部配置。 示例: REST_FRAMEWORK={ 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) } class BookView(ListAPIView): ... filter_fields = ('name',) #配置可以按照哪个字段来过滤
4.2 排序
示例:
# 视图
from rest_framework.filters import OrderingFilter
class BooksView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [OrderingFilter]
ordering_fields = ('id', 'price')
# urls.py
path('books/', views.BooksView.as_view()),
# 使用
http://127.0.0.1:8000/books/?ordering=-price
http://127.0.0.1:8000/books/?ordering=price
http://127.0.0.1:8000/books/?ordering=-id
- ie6,ie7,ff 的css兼容hack写法
- 使用子查询时应当注意的
- LegacyText的复制的Bug
- 提高WCF服务并发能力的简单处理办法
- 如何给已经有数据的DataTable动态增加一列并赋值
- Gitlab上采用rpm方式快速安装的操作记录
- WCF与IIS集成Windows身份验证的矛盾
- openstack中彻底删除计算节点的操作记录
- 验证码无刷新更换
- 从MapX到MapXtreme2004[12]-SearchNearest!
- Sublime Text的安装与配置
- 复制到浮动层,强调显示某个(多个)区域
- Jquery实现的一种常用高亮效果
- MaCfee导致Asp.net/Jmail无法发送邮件的解决办法
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 库的安装及使用 常见错误异常及解决办法
- Kafka三种可视化监控管理工具Monitor/Manager/Eagle
- 超性感的React Hooks(五):自定义hooks
- 三、变量对象
- Java编程 经验技巧汇总
- 关于IP地址的一些相关知识点
- vmware的三种网络模式
- 我的 Chrome 版本不支持生成二维码,30 分钟怒怼了一个插件,附源码
- Android开发(第一行代码 第二版) 常见异常和解决办法(基于Android Studio)(二)
- 大厂Java项目如何进行Maven多模块管理
- Android开发 经验技巧汇总(基于Android Studio)(一)
- 老板逼我用 Git,本地指令介绍
- Python全栈(三)数据库优化之5.MySQL自关联、外键与Python操作MySQL
- Android开发 经验技巧汇总(基于Android Studio)(二)
- 表格滑动和图片链接,mdnice安排上了!