本节大纲

  1、Permissions

  2、Throttling

Permissions

权限是用来授权或者拒绝用户访问API的不同部分的不同的类的。基础的权限划分

1、IsAuthenticated
允许任何通过认证的用户访问,拒绝任何没有通过认证的用户。 2、IsAuthenticatedOrReadOnly
认证通过的用户有所有访问权限,反之只有只读权限

权限的定义

rest框架内的权限总是被定义成一个权限类的列表。主视图运行前检查,失败就引发exceptions.PermissionDenied或者exceptions.NotAuthenticated异常

权限检查失败会根据下面的情况返回'403 Forbidden'或'401 Unauthorized':

1、请求验证成功,权限拒绝  # 返回HTTP 403 Forbidden响应
2、请求没有验证成功,最上面的验证类没有使用'WWW-Authenticate'头 # 返回'HTTP 403 Forbidden' 响应
3、请求没有认证成功,最上面的认证类没有使用'WWW-Authenticate'头 # 返回'HTTP 401 Unauthorized'响应,带有一个合适的WWW-Authenticate头

对象级别的权限

在rest框架内,存在于一般视图的.get_object()方法里,如果不允许,引发exceptions.PermissionDenied异常。

 

如果您正在编写自己的视图,并且希望强制执行对象级别的权限,或者如果您在一般视图上重写.get_object()方法,那么您将需要在检索对象时显式地调用视图上的.check_object_per.(request,obj)方法。失败则引发PermissionDenied或者NotAuthenticated异常

def get_object(self):
obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
self.check_object_permissions(self.request, obj)
return obj

对象级别权限的限制

事实上,因为效率原因通用视图不会自动应用对象级别的权限到每一个实例里。通常,当使用对象级别权限时,还希望适当地过滤queryset,以确保用户只对它们允许查看的实例具有可见性。

设置权限策略

默认可以全局设置,使用DEFAULT_PERMISSION_CLASSES

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}

如果没有指定,默认设定是允许不受限制的访问

'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)

在CBV的View或者ViewSet上

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)

在FBV上

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)

API Reference

1、AllowAny

允许不受限制的访问,无论请求有没有被认证。

2、IsAuthenticated

拒绝没有通过认证的用户。适用于API只允许注册用户访问

3、IsAdminUser

拒绝任何的用户,除非user.is_staff为True才能访问

4、IsAuthenticatedOrReadOnly

允许通过认证的用户执行任何请求,没有通过认证的用户是只读权限,安全方法:GETHEAD 或者 OPTIONS.

DjangoModelPermissions

此权限绑定到Django标准的django.contrib.auth 模型权限。必须纸杯应用于有.queryset属性的视图。只有被认证并有相关模型权限的用户才能被授权

POST  # 对应model的add权限
PUT和PATCH # 对应model的change权限
delete # 对应model的delete权限

视图不包含queryset属性

如果view里面没有queryset,而是重写了get_queryset()方法,在这种案例里面,我们还建议用前哨查询设置标记视图,这样类能决定需要的权限。

queryset = User.objects.none()  # Required for DjangoModelPermissions

DjangoModelPermissionOrAnonReadOnly

跟DjangoModelOermissions很像,没有认证的用户只读权限

DjangoObjectPermission

跟DjangoModelPermissions一样

Custom Permission

实施客制化权限,重写BasePermission,实行下面的方法中的一个或多个

.has_permission(self, request, view)
.has_object_permission(self, request, view, obj)

这些方法在应该授权时返回True。你需要测试请求是读操作或写操作,应该检查请求方法是否在'GET', 'OPTIONS'和'HEAD' 组成的SAFE_METHODS里面

if request.method in permissions.SAFE_METHODS:
# Check permissions for read-only request
else:
# Check permissions for write request

has_object_permission方法只有在通过视图级别的has_permission方法时才会被调用。另外为了让实例级别的检查运行,视图代码应该显式的调用.check_object_permissions(request, obj). 如果你使用通用视图,默认将自动处理。

检查失败会引发PermissionDenied异常。改变错误信息跟异常绑定,在你的客制化权限里面申明message。否则PermissionDenied的default_detail属性将被使用

from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission):
message = 'Adding customers not allowed.' def has_permission(self, request, view):
...

示例

from rest_framework import permissions

class BlacklistPermission(permissions.BasePermission):
"""
Global permission check for blacklisted IPs.
""" def has_permission(self, request, view):
ip_addr = request.META['REMOTE_ADDR']
blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
return not blacklisted

跟全局设置很像,你可以创建一个对象级别的权限对所有到来的请求,只有通过的能操作一个特殊的对象实例。

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

节流(throttling)在rest框架内总是被定义成一组类的列表。同样在主题视图之前执行检查,失败引发exceptions.Throttled异常

设置节流策略

全局设置使用DEFAULT_THROTTLE_CLASSES和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'
}
}

DEFAULT_THROTTLE_RATES可以包含second, minute, hour或day作为节流周期。

你也可以为每个视图或者视图集设置节流,CBV格式

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)

在FBV里面

@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def example_view(request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)

设置缓存

节流类是REST框架提供的,使用了Django的缓存后端。你应该确保已经设置了合适的缓存设定。

如果你想使用一个缓存而不是默认的'default',你可以创建客制化的节流类并设置缓存cache属性

class CustomAnonRateThrottle(AnonRateThrottle):
cache = get_cache('alternate')

别忘了设置DEFAULT_THROTTLE_CLASSES或者使用throttle_classes视图属性

API Reference

AnonRateThrottle

AnonRateThrottle只限制没有认证的用户。访问请求的IP地址被用来生成唯一的键用来做限制。从下面几个方面来做请求率限制

1、类上的rate属性重写AnonRateThrottle并设置此属性
2、DEFAULT_THROTTLE_RATES['anon']设置

AnonRateThrottle很适合做对于未知资源请求的限制

UserRateThrottle

UserRateThrottle将通过一个给定的API速率来限制用户在API上的请求。用户的ID被用来生成唯一的节流键。未认证的请求将使用IP地址来生成唯一节流键。

请求的限定方面

1、rate属性,重写的UserRateThrottle,设置此属性
2、DEFAULT_THROTTLE_RATES['user']设置

一个API可能同时有多个UserRateThrottle在同一个地方。所以你需要重写UserRateThrottle并设置唯一'scope'为每一个类

class BurstRateThrottle(UserRateThrottle):
scope = 'burst' class SustainedRateThrottle(UserRateThrottle):
scope = 'sustained'
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'example.throttles.BurstRateThrottle',
'example.throttles.SustainedRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'burst': '60/min',
'sustained': '1000/day'
}
}

UserRateThrottle适用于如果想简单全局限制每位用户的速率。

ScopedRateThrottle

ScopedRateThrottle类被用来限制访问API的特殊部分。只有被访问的视图包含.throttle_scope属性时节流才被应用。然后,通过将请求的“scope”与唯一的用户ID或IP地址串联,形成唯一的节流键。被允许的请求速率被设置里面的DEFAULT_THROTTLE_RATES决定,通过使用键值scope

class ContactListView(APIView):
throttle_scope = 'contacts'
... class ContactDetailView(APIView):
throttle_scope = 'contacts'
... class UploadView(APIView):
throttle_scope = 'uploads'
...

然后设置全局

REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.ScopedRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'contacts': '1000/day', # 1000requests per day
'uploads': '20/day' # 20request per day
}
}

自定义 throttles

创建一个自定义节流,重写BaseThrottle执行.allow_request(self, request, view). 这个方法应该返回True如果请求应该被允许,否则False。同时你也需要重写.wait()方法,如果执行,.wait()方法讲返回一个推荐的的秒数在视图下一次请求之前。.wait()方法只有在.allow_request()返回false的时候将被调用

import random

class RandomRateThrottle(throttling.BaseThrottle):
def allow_request(self, request, view):
return random.randint(1, 10) != 1

Django REST Framework API Guide 07的更多相关文章

  1. Django REST Framework API Guide 01

    之前按照REST Framework官方文档提供的简介写了一系列的简单的介绍博客,说白了就是翻译了一下简介,而且翻译的很烂.到真正的生产时,就会发现很鸡肋,连熟悉大概知道rest framework都 ...

  2. Django REST Framework API Guide 03

    本节大纲 1.Routers 2.Parsers 3.Renderers Routers Usage from rest_framework import routers router = route ...

  3. Django REST Framework API Guide 08

    1.Filtering 2.Pagination FIltering GenericAPIView的子类筛选queryset的简单方法是重写.get_quueryset()方法. 1.根据当前用户进行 ...

  4. Django REST Framework API Guide 06

    本节大纲 1.Validators 2.Authentication Validators 在REST框架中处理验证的大多数时间,您将仅仅依赖于缺省字段验证,或在序列化器或字段类上编写显式验证方法.但 ...

  5. Django REST Framework API Guide 04

    本节大纲 1.serializers 1.Serializers Serializers允许复杂的数据,像queryset和模型实例转换成源生的Python数据类型.从而可以更简单的被渲染成JSON, ...

  6. Django REST Framework API Guide 02

    本节大纲 1.Generic Views 2.ViewSets  1.Generic Views CBV的主要的一个优点就是极大的允许了对于代码的从用.自然,rest framework取其优势,提供 ...

  7. Django REST Framework API Guide 05

    本节大纲 1.Serializer fields 2.Serializer relations Serializer fields 1.serializer 字段定义在fields.py文件内 2.导 ...

  8. Django Rest Framework API指南

    Django Rest Framework API指南 Django Rest Framework 所有API如下: Request 请求 Response 响应 View 视图 Generic vi ...

  9. tastypie Django REST framework API [Hello JSON]

    tastypie is a good thing. Haven't test it thoroughly. Gonna need some provement. Now I will introduc ...

随机推荐

  1. SQL瓶颈分析,以及适应最佳执行计划的探讨

    原文地址:   https://blog.csdn.net/daiqiulong2/article/details/86546446?tdsourcetag=s_pcqq_aiomsg 年纪大了,慢慢 ...

  2. 分布式 cephfs

    参考链接: http://docs.ceph.com/docs/mimic/cephfs/

  3. ksar、sar及相关内核知识点解析

    关键词:sar.sadc.ksar./proc/stat./proc/cpuinfo./proc/meminfo./proc/diskstats. 在之前有简单介绍过sar/ksar,最近在使用中感觉 ...

  4. One take,可望而不可即

    One take,是几年之前看综艺节目听林志炫提到的一个词,就是说录制一首歌曲一次性完成,无需后期的各种修音.这个概念听起来就很酷,对不对? 作为一个程序员,我经常也希望能够One take:一次性把 ...

  5. Nginx(四)------nginx 负载均衡

    在上一篇博客我们介绍了 Nginx 一个很重要的功能——代理,包括正向代理和反向代理.这两个代理的核心区别是:正向代理代理的是客户端,而反向代理代理的是服务器.其中我们又重点介绍了反向代理,以及如何通 ...

  6. js修改父子json格式成树状结构格式

    js修改父子json成树状结构 var json = [ { "id" : "01", "pId":"" } , { & ...

  7. LeetCode 613. Shortest Distance in a Line

    Table point holds the x coordinate of some points on x-axis in a plane, which are all integers. Writ ...

  8. PyQt5基础应用一

    一.PyQt5基础   1.1 创建窗口 import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__ ...

  9. vue 限制输入字符长度

    一.watch方法: <input v-model="textareaValue" type="textarea" placeholder="请 ...

  10. [模板] k短路

    简介 Dijkstra最短路+A*搜索. 先逆向求所有点到终点的最短路 \(dis[i]\). 定义估价函数 \(f[i] = d[i] + dis[i]\) , 其中 \(d[i]\) 表示当前起点 ...