API Guide(十四)之Permissions

权限

身份验证或身份识别本身通常不足以获取信息或代码的访问权限。为此,请求访问的实体必须具有授权。

苹果开发者文档

连同认证限制,权限决定是否应该授予请求或拒绝访问。

在允许继续执行任何其他代码之前,权限检查始终在视图的开始处运行。权限检查通常将使用在所述认证信息request.userrequest.auth属性,以确定是否输入请求应该被允许。

权限用于授予或拒绝将不同类别的用户访问到API的不同部分。

最简单的权限是允许访问任何经过身份验证的用户,并拒绝访问任何未经身份验证的用户。这对应IsAuthenticated于REST框架中的类。

稍微严格的权限风格将是允许对经过身份验证的用户的完全访问,但允许对未经身份验证的用户的只读访问。这对应IsAuthenticatedOrReadOnly于REST框架中的类。

如何确定权限

REST框架中的权限始终被定义为许可类列表。

在运行主视图之前,检查列表中的每个权限。如果任何权限检查失败exceptions.PermissionDeniedexceptions.NotAuthenticated异常将被提升,视图的主体将不会运行。

当权限检查失败时,将返回“403禁止”或“401未授权”响应,根据以下规则:

  • 请求已成功通过身份验证,但权限被拒绝。 - 将返回HTTP 403 Forbidden响应。
  • 请求未成功认证,最高优先级的认证类使用WWW-Authenticate标头。 - 将返回HTTP 403 Forbidden响应。
  • 请求未成功认证,最高优先级的认证类确实使用WWW-Authenticate标头。- 返回HTTP 401未经授权的响应,并附带适当的WWW-Authenticate标题。

对象级权限

REST框架权限还支持对象级的许可。对象级权限用于确定是否允许用户对特定对象(通常是模型实例)采取行动。

调用对象级权限由REST框架的通用视图运行.get_object()。与视图级别权限一样,exceptions.PermissionDenied如果用户不允许对给定对象采取行动,则会引发异常。

如果您正在编写自己的视图并希望强制执行对象级权限,或者如果get_object在通用视图中覆盖该方法,那么您需要在检索到的位置显式调用.check_object_permissions(request, obj)视图上的方法目的。

这将引发PermissionDeniedNotAuthenticated异常,或者如果视图具有适当的权限,则返回。

例如:

def get_object(self):
    obj = get_object_or_404(self.get_queryset())
    self.check_object_permissions(self.request, obj)
    return obj

对象级权限的限制

出于性能原因,当返回对象列表时,通用视图将不会自动将对象级别的权限应用于查询集中的每个实例。

通常当您使用对象级权限时,您还需要适当地过滤查询集,以确保用户只能在允许查看的实例上查看。

设置权限策略

使用该DEFAULT_PERMISSION_CLASSES设置可以全局设置默认权限策略。例如。

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

如果未指定,此设置默认为允许无限制访问:

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

您还可以使用基于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)

注意:当您通过类属性或装饰器设置新的权限类时,您会告诉该视图忽略在settings.py文件中设置的默认列表。


API参考

AllowAny

AllowAny许可类将允许不受限制的访问,不管请求被认证或未认证的

由于您可以通过使用空列表或元组来执行权限设置来实现相同的结果,但是您可能会发现指定此类是很有用的,因为它使用户的意图是明确的。

IsAuthenticated

IsAuthenticated许可类将拒绝允许任何未认证用户,并允许许可,否则。

如果您希望您的API只能由注册用户访问,则此权限是合适的。

IsAdminUser

所述IsAdminUser许可类将拒绝许可给任何用户,除非user.is_staffTrue在这种情况下的许可将被允许。

如果您希望您的API只能由受信任的管理员的子集访问,则此权限是合适的。

IsAuthenticatedOrReadOnly

IsAuthenticatedOrReadOnly将允许经过身份验证的用户执行任何请求。如果请求方式是“安全”方法之一,则只允许未经授权的用户的请求; GETHEADOPTIONS

如果您希望您的API允许匿名用户的读取权限,并且只允许对经过身份验证的用户的写入权限,则此权限是合适的。

DjangoModelPermissions

此权限类与Django的标准django.contrib.auth 模型权限相关。此权限只能应用于具有.queryset属性集的视图。仅当用户进行身份验证并分配了相关的模型权限时,才会授予授权。

  • POST请求要求用户对add模型拥有权限。
  • PUT并且PATCH请求要求用户对change模型具有许可。
  • DELETE请求要求用户对delete模型拥有权限。

也可以覆盖默认行为以支持自定义模型权限。例如,您可能需要viewGET请求添加模型权限。

要使用自定义模型权限,请覆盖DjangoModelPermissions并设置.perms_map属性。有关详细信息,请参阅源代码。

使用不包含queryset属性的视图。

如果您使用此权限使用覆盖get_queryset()方法queryset的视图,则视图上可能没有属性。在这种情况下,我们建议使用哨兵查询器标记视图,以便此类可以确定所需的权限。例如:

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

DjangoModelPermissionsOrAnonReadOnly

类似于DjangoModelPermissions,但也允许未经身份验证的用户对API具有只读访问权限。

DjangoObjectPermissions

该权限类与Django的标准对象许可框架相关联,允许对模型进行每个对象的权限。为了使用此权限类,您还需要添加支持对象级权限的权限后端,例如django-guardian

DjangoModelPermissions此相反,此权限只能应用于具有.queryset属性或.get_queryset()方法的视图。仅当用户进行身份验证并具有分配相关的每个对象权限相关模型权限时,授权才被授予。

  • POST请求要求用户拥有add模型实例的权限。
  • PUT并且PATCH请求要求用户对change模型实例拥有权限。
  • DELETE请求要求用户拥有delete模型实例的权限。

请注意,DjangoObjectPermissions 要求django-guardian包,并且应该支持其他对象级后端同样出色。

与之一样,DjangoModelPermissions您可以通过覆盖DjangoObjectPermissions和设置.perms_map属性来使用自定义模型权限。有关详细信息,请参阅源代码。



注意:如果你需要的对象级别view的权限GETHEADOPTIONS请求,你要还考虑增加的DjangoObjectPermissionsFilter类,以确保该列表只端点返回结果包括用户拥有适当的查看权限的对象。



自定义权限

要实现自定义权限,请覆盖BasePermission并实现以下方法之一或两者:

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

True如果请求被授予访问权限,则返回方法,否则返回False

如果您需要测试如果请求是读操作或写操作,你应该检查对常量的请求方法SAFE_METHODS,这是一个包含一个元组‘GET‘‘OPTIONS‘‘HEAD‘。例如:

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请直接在自定义权限上实现属性。否则将使用default_detail属性PermissionDenied

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 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

请注意,通用视图将检查适当的对象级权限,但如果您正在编写自己的自定义视图,则需要确保检查对象级别权限。您可以通过self.check_object_permissions(request, obj)从视图调用具有对象实例的方式来执行此操作。APIException如果任何对象级权限检查失败,此调用将提出适当的,否则将简单地返回。

另请注意,通用视图将仅检查检索单个模型实例的视图的对象级权限。如果需要对列表视图进行对象级过滤,则需要单独过滤查询集。有关详细信息,请参阅过滤文档


第三方包

以下第三方软件包也可用。

组合权限

组成权限包提供了一种简单的方式来定义复杂和多深度(与逻辑运算符)权限对象,使用小的和可重复使用的部件。

REST条件

静止状态下包装的另一个扩展简单和方便的方式构建复杂的权限。该扩展允许您将权限与逻辑运算符组合。

干休息权限

DRY休息权限包提供定义单个默认和自定义操作不同的权限的能力。此软件包适用于具有应用程序数据模型中定义关系的权限的应用程序。它还支持通过API的串行器返回给客户端应用程序的权限检查。此外,它还支持向默认和自定义列表操作添加权限,以限制每个用户检索的数据。

Django Rest框架角色

Django的REST框架角色包使得它更容易在多个类型的用户参数的API。

Django Rest Framework API密钥

Django的REST框架API密钥包,您可以确保服务器的每个请求需要一个API密钥头。您可以从django管理界面生成一个。

时间: 2024-08-27 00:36:36

API Guide(十四)之Permissions的相关文章

微信小程序把玩(三十四)Audio API

原文:微信小程序把玩(三十四)Audio API 没啥可值得太注意的地方 重要属性: 1. wx.getBackgroundAudioPlayerState(object) 获取播放状态 2.wx.playBackgroundAudio(object)播放音乐 3.wx.pauseBackgroundAudio()暂停音乐 4.wx.seekBackgroundAudio(object) 设置播放进度 5.wx.stopBackgroundAudio()停止播放音乐 三个监听器: wxml <b

处女男学Android(十四)---Android 重量级数据存储之SQLite

前言 不知不觉的Android基础系列已经写了十三篇了,这是第十四篇~上一篇blog记录了Android中的一种数据存储方案,即共享参数(Sharedpreferences)的使用(处女男学Android(十三)---Android 轻量级数据存储之SharedPreferences).最近初学如何在Android中应用SQLite,写了一个基于ListView的增删查的小例子,本篇blog就记录一下我学习到的如何在Android中操作SQLite持久化客户端数据. 初始化SQLite 关于SQ

对硅谷和硅谷科技公司的十四问,全程干货

引用: http://www.36kr.com/p/219345.html 从硅谷公司哪家强,到人人在议的泡沫问题,大数据和人工智能如何结合?2015年的科技前瞻是怎样一副图景?来自硅谷的Coursera软件工程师董飞将其近日在斯坦福公开讲座上的干货和各种场合的问答整理出来和大家分享.文中有他的一手从业经验,也有其对亲身就职或深度研究过的一些公司具体分析,如Hadoop.Amazon.LinkedIn等.董飞的知乎页面在这里,邮箱是[email protected]. 1.目前硅谷最火最有名的高

C#编程总结(十四)dynamic

C#编程总结(十四)dynamic 介绍 Visual C# 2010 引入了一个新类型 dynamic. 该类型是一种静态类型,但类型为 dynamic 的对象会跳过静态类型检查. 大多数情况下,该对象就像具有类型 object 一样. 在编译时,将假定类型化为 dynamic 的元素支持任何操作. 因此,您不必考虑对象是从 COM API.从动态语言(例如 IronPython).从 HTML 文档对象模型 (DOM).从反射还是从程序中的其他位置获取自己的值. 但是,如果代码无效,则在运行

Chrome浏览器扩展开发系列之十四:本地消息机制Native messagin

Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 2016-11-24 09:36 114人阅读 评论(0) 收藏 举报  分类: PPAPI(27)  通过将浏览器所在客户端的本地应用注册为Chrome浏览器扩展的"本地消息主机(native messaging host)",Chrome浏览器扩展还可以与客户端本地应用之间收发消息. 客户端的本地应用注册为Chrome浏览器扩展的"本地消息主机"之后,Chrome浏览器会在独立的

第三百二十四节,web爬虫,scrapy模块介绍与使用

第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrapy 使用了 Twisted异步网络库来处理网络通讯.

JavaScript高级程序设计:第十四章

第十四章 一.表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型.HTMLFormElement继承了HTMLElement,因而与其他HTML元素具有相同的默认属性.不过,HTMLFormElement也有它自己下列独有的属性和方法. 取得<form>元素的引用方式有好几种.其中最常见的方式就是将它看成与其他元素一样,并为其添加id特性,然后再像下面这样使用getElementById()方

云计算设计模式(二十四)——仆人键模式

云计算设计模式(二十四)——仆人键模式 使用一个令牌或密钥,向客户提供受限制的直接访问特定的资源或服务,以便由应用程序代码卸载数据传输操作.这个模式是在使用云托管的存储系统或队列的应用中特别有用,并且可以最大限度地降低成本,最大限度地提高可扩展性和性能. 背景和问题 客户端程序和网络浏览器经常需要读取和写入文件或数据流,并从一个应用程序的存储空间.通常,应用程序将处理的运动数据,或者通过从存储读取它,并将其传输到客户端,或通过从客户机读取该载流并将其存储在数据存储中.然而,这种方法吸收了宝贵的资

Chrome浏览器扩展开发系列之十四

Chrome浏览器扩展开发系列之十四:本地消息机制Native messaging 时间:2015-10-08 16:17:59      阅读:1361      评论:0      收藏:0      [点我收藏+] 通过将浏览器所在客户端的本地应用注册为Chrome浏览器扩展的"本地消息主机(native messaging host)",Chrome浏览器扩展还可以与客户端本地应用之间收发消息. 客户端的本地应用注册为Chrome浏览器扩展的"本地消息主机"