django-rest-framework框架总结之认证权限限流过滤分页及异常处理
Posted 七月的小尾巴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django-rest-framework框架总结之认证权限限流过滤分页及异常处理相关的知识,希望对你有一定的参考价值。
认证 Authentication
REST 框架提供了几种即用的身份验证方案,并且支持实现自定义认证。
我们需要在 setting.py
文件中设置 DEFAULT_AUTHENTICATION_CLASSES
全局默认身份验证方案。例如。
REST_FRAMEWORK =
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
还可以基于每个视图或每个视图集设置 permission_classes
,且视图中定义的认证方案会高于 DEFAULT_AUTHENTICATION_CLASSES
全局配置 。
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
content =
'user': str(request.user), # `django.contrib.auth.User` instance.
'auth': str(request.auth), # None
return Response(content)
或者我们也可以使用装饰器 @api_view
结合函数视图一起使用。
@api_view(['GET'])
@authentication_classes([SessionAuthentication, BasicAuthentication])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
content =
'user': str(request.user), # `django.contrib.auth.User` instance.
'auth': str(request.auth), # None
return Response(content)
认证失败通常会有两种响应:
- HTTP 401 Unauthorized 未认证
- HTTP 403 Permission Denied 权限被禁止
权限 Permissions
权限控制可以限制用于对于视图的访问和对于具体数据对象的访问。
- 在 执行视图的 dispatch() 方法前,会先进行视图访问权限的判断。
- 在通过 get_object() 获取具体对象时,会进行对象访问权限的判断。
设置权限策略
可以使用该设置全局设置默认 DEFAULT_PERMISSION_CLASSES
权限策略。例如
REST_FRAMEWORK =
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
如果配置文件中未指明,则设置默认为允许无限制访问
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
DRF中提供的权限策略
AllowAny
允许所有用户IsAuthenticated
仅通过认证的用户IsAdminUser
仅管理员用户IsAuthenticatedOrReadOnly
认证的用户可以完全操作,否则只能 Get 读取
还可以基于每个视图或者每个视图集设置身份验证策略,使用基于 APIView
类的视图。
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
content =
'status': 'request was permitted'
return Response(content)
或者 可以使用 api_view
装饰器与基于函数的视图一起使用。
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
content =
'status': 'request was permitted'
return Response(content)
注意:类属性或装饰器设置新的权限类时,他的优先级会高于 setting.py 文件中的配置。
如果他们继承自 rest_framework.permissions.BasePermission
,IsAuthenticatedOrReadOnly
,则可以使用标准Python 按位运算符组合权限。
from rest_framework.permissions import BasePermission, IsAuthenticated, SAFE_METHODS
from rest_framework.response import Response
from rest_framework.views import APIView
class ReadOnly(BasePermission):
def has_permission(self, request, view):
return request.method in SAFE_METHODS
class ExampleView(APIView):
permission_classes = [IsAuthenticated|ReadOnly]
def get(self, request, format=None):
content =
'status': 'request was permitted'
return Response(content)
注意:
它支持&(和),|(或)和~(不是)。
自定义权限策略
如需自定义权限,需要继承 rest_framework.permissions.BasePermission
父类,并实现以下任何一种方法,或者全部
.has_permission(self, request, view)
: 是否可以访问视图,view 表示当前视图对象.has_object_permission(self, request, view, obj)
: 是否可以访问数据对象,view 表示当前视图,ojb 为数据对象
如果应向请求授予访问权限,则应返回 True
,否则应返回 False
.
如果测试失败,自定义权限将引发异常。若要更改与异常关联的错误消息,请直接在自定义权限上实现属性。
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
...
示例
下面是一个权限类示例,该权限类根据阻止列表检查传入请求的 IP 地址,并在 IP 被阻止时拒绝请求。
from rest_framework import permissions
class BlocklistPermission(permissions.BasePermission):
"""
Global permission check for blocked IPs.
"""
def has_permission(self, request, view):
ip_addr = request.META['REMOTE_ADDR']
blocked = Blocklist.objects.filter(ip_addr=ip_addr).exists()
return not blocked
除了针对所有传入请求运行的全局权限外,您还可以创建对象级权限,这些权限仅针对影响特定对象实例的操作运行。例如:
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
# Instance must have an attribute named `owner`.
return obj.owner == request.user
限流 Throttling
限流 可以对接口的访问频次进行限制,以减轻服务器压力。
设置限流策略
可以在配置文件中,使用 DEFAULT_THROTTLE_RATES
中进行全局配置。
REST_FRAMEWORK =
'DEFAULT_THROTTLE_CLASSES': [
# 适用于任何用户对接口访问的限制
'rest_framework.throttling.AnonRateThrottle',
# 登录用户对接口访问的限制
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES':
'anon': '100/day',
'user': '1000/day'
AnonRateThrottle
: 限制所有匿名未认证的用户,使用 IP 区分用户。UserRateThrottle
:限制认证用户,使用 user_id 来区分ScopedRateThrottle
: 限制用户对于每个视图访问频次,使用 IP 或者 user_id
DEFAULT_THROTTLE_RATES
可以使用 second , minute,hour, 或者 day 来指定周期。
同样还可以基于每个视图或者每个视图集设置限流策略,使用基于类视图。
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
class ExampleView(APIView):
throttle_classes = [UserRateThrottle]
def get(self, request, format=None):
content =
'status': 'request was permitted'
return Response(content)
如果将装饰器 @api_view
与基于函数的视图一起使用,则可以使用以下装饰器。
@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def example_view(request, format=None):
content =
'status': 'request was permitted'
return Response(content)
还可以为使用 @action
装饰器创建的路由设置限制类。 以这种方式设置的限制类将覆盖任何视图集级别类设置。
@action(detail=True, methods=["post"], throttle_classes=[UserRateThrottle])
def example_adhoc_method(request, pk=None):
content =
'status': 'request was permitted'
return Response(content)
ScopedRateThrottle 自定义限流
REST_FRAMEWORK =
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle'
],
'DEFAULT_THROTTLE_RATES':
'uploads': '100/day',
'contacts': '1000/day'
class ExampleView(APIView):
throttle_scope = "contacts"
过滤
…
分页
…
异常处理
…
以上是关于django-rest-framework框架总结之认证权限限流过滤分页及异常处理的主要内容,如果未能解决你的问题,请参考以下文章
django-rest-framework框架总结之View视图之APIViewGenericAPIView视图集ViewSet
python django-rest-framework 3.3.3 更新嵌套序列化程序