restframework 权限流程 及自定义权限类

一.请求来到之后,都要先执行dispatch方法

 def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django‘s regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        self.args = args
        self.kwargs = kwargs
        第一步:对request进行加工(添加数据)
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            #第二步:
                #处理版权信息
                #认证
                #权限
                #请求用户进行访问频率的限制
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            # 第三步、执行:get/post/put/delete函数
            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        #第四步、 对返回结果再次进行加工
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

二.下面我们直接分析第二步

1.self.initial(request,*args,*kwargs)可以看到做了以下操作

def initial(self, request, *args, **kwargs):
        """
        Runs anything that needs to occur prior to calling the method handler.
        """
        self.format_kwarg = self.get_format_suffix(**kwargs)

        # Perform content negotiation and store the accepted info on the request
        neg = self.perform_content_negotiation(request)
        request.accepted_renderer, request.accepted_media_type = neg

        # Determine the API version, if versioning is in use.
        #2.1 处理版本信息
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme

        # Ensure that the incoming request is permitted
        #2.2 认证
        self.perform_authentication(request)
        # 2.3 权限
        self.check_permissions(request)
        # 2.4 请求用户进行访问频率的限制
        self.check_throttles(request)

2.self.check_permissions(request)具体干了什么

def check_permissions(self, request):
        # 遍历权限对象列表得到一个个权限对象(权限器),进行权限认证
        for permission in self.get_permissions():
            # 权限类一定有一个has_permission权限方法,用来做权限认证的
            # 参数:权限对象self、请求对象request、视图类对象
            # 返回值:有权限返回True,无权限返回False
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request, message=getattr(permission, ‘message‘, None)
                )

3.其中循环遍历了self.get_permissions() 我们可以点进去看看  这里到底返回的什么

    def get_permissions(self):
        """
        Instantiates and returns the list of permissions that this view requires.
        """
        return [permission() for permission in self.permission_classes]

4.进去后发现了一个熟悉的self.permission_classes 是api_settings中的系统权限类

    ‘DEFAULT_PERMISSION_CLASSES‘: [
        ‘rest_framework.permissions.AllowAny‘,
    ],

 5.这四个系统权限类,我们他们具体看看做了些什么

"""
1)AllowAny:
    认证规则全部返还True:return True
        游客与登陆用户都有所有权限

2) IsAuthenticated:
    认证规则必须有登陆的合法用户:return bool(request.user and request.user.is_authenticated)
        游客没有任何权限,登陆用户才有权限

3) IsAdminUser:
    认证规则必须是后台管理用户:return bool(request.user and request.user.is_staff)
        游客没有任何权限,登陆用户才有权限

4) IsAuthenticatedOrReadOnly
    认证规则必须是只读请求或是合法用户:
        return bool(
            request.method in SAFE_METHODS or
            request.user and
            request.user.is_authenticated
        )
        游客只读,合法用户无限制
"""

6.分析以上四个系统权限类,他们返回值都是bool值  都是判断各自的想要实现的认证规则,因此我们也可以模仿他们写一个这样的自定义权限类

自定义权限类

全局配置:settings.py

REST_FRAMEWORK = {
    # 权限类配置
    ‘DEFAULT_PERMISSION_CLASSES‘: [
        ‘rest_framework.permissions.AllowAny‘,
    ],
}  

这是全局配置,而且其中是AllowAny 游客和登录用户都有所有权限  因此 我们可以配置局部配置

局部配置 :views.py

# api/views.py
from rest_framework.permissions import IsAuthenticated
class TestAuthenticatedAPIView(APIView):
    permission_classes = [IsAuthenticated]
    def get(self, request, *args, **kwargs):
        return APIResponse(0, ‘test 登录才能访问的接口 ok‘)

自定义权限类

"""
1) 创建继承BasePermission的权限类
2) 实现has_permission方法
3) 实现体根据权限规则 确定有无权限
4) 进行全局或局部配置

认证规则
i.满足设置的用户条件,代表有权限,返回True
ii.不满足设置的用户条件,代表有权限,返回False
"""
# utils/permissions.py
from rest_framework.permissions import BasePermission
from django.contrib.auth.models import Group
class MyPermission(BasePermission):
    def has_permission(self, request, view):
        # 只读接口判断
        r1 = request.method in (‘GET‘, ‘HEAD‘, ‘OPTIONS‘)
        # group为有权限的分组
        group = Group.objects.filter(name=‘管理员‘).first()
        # groups为当前用户所属的所有分组
        groups = request.user.groups.all()
        r2 = group and groups
        r3 = group in groups
        # 读接口大家都有权限,写接口必须为指定分组下的登陆用户
        return r1 or (r2 and r3)

#views.py
# 游客只读,登录用户只读,只有登录用户属于 管理员 分组,才可以增删改
from utils.permissions import MyPermission
class TestAdminOrReadOnlyAPIView(APIView):
    permission_classes = [MyPermission]
    # 所有用户都可以访问
    def get(self, request, *args, **kwargs):
        return APIResponse(0, ‘自定义读 OK‘)
    # 必须是 自定义“管理员”分组 下的用户
    def post(self, request, *args, **kwargs):
        return APIResponse(0, ‘自定义写 OK‘)

原文地址:https://www.cnblogs.com/s686zhou/p/11721214.html

时间: 2024-08-30 02:13:37

restframework 权限流程 及自定义权限类的相关文章

[android开发篇]自定义权限

有时候,我们可能遇到如下需求场景:当用户在一个应用程序中进行某项操作时,会启动另外一个应用程序,最常见的时直接打开了另外一个应用程序,并进入其中某个Activity(如:有的应用中有推荐应用列表,当用户点击时程序会首先判断其他应用有无安装,若无则提示用户下载,如有则直接打开进入).有时候,处于安全等需要,此类操作需要加上受限制性的访问限制,那么怎么办呢?Android中为我们提供了自定义权限. 为了讲清自定义权限,先以不同的程序之间访问Activity增加权限限制为例.假设应用程序A中有Main

DRF之自定义权限

1.增加表字段: from django.db import models class UserInfo(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) email = models.CharField(max_length=64) user_type_choices = ((0,'普通用户'),(1,'管理员')) user_type = m

springboot2.0整合springsecurity前后端分离进行自定义权限控制

在阅读本文之前可以先看看springsecurity的基本执行流程,下面我展示一些核心配置文件,后面给出完整的整合代码到git上面,有兴趣的小伙伴可以下载进行研究 使用maven工程构建项目,首先需要引入最核心的依赖, <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <

android 自定义权限

理解android的自定义权限,下面介绍一段代码.包括两个安卓项目,project 2试图调用project 1中的特权活动PrivActivity. android project 1 : application name: Custom Permission pacakage name: com.cust.perm 1) 特权活动 PrivActivity.java package com.cust.perm; import android.app.Activity; import andr

shiro 实现自定义权限规则校验

<span style="font-family: Arial, Helvetica, sans-serif;">在系统中使用shiro进行权限管理,当用户访问没有权限的资源时会跳转到指定的登录url.</span> 但是如果系统中支持手机app,手机访问时没有使用session进行登录凭证管理,而是使用token,有两种解决方法: 1:支持手机客户端访问的资源在权限配置中配置成anon 2:实现自定义认证拦截器,对用户请求资源进行认证 显然第一种方法不适用,这

XAF-如何实现自定义权限系统用户对象

本示例使用XPO. 新建一个XAF项目.填加两个类进来: [DefaultClassOptions] public class Employee : Person { public Employee(Session session) : base(session) { } [Association("Employee-Task")] public XPCollection<EmployeeTask> OwnTasks { get { return GetCollection

【转】 Pro Android学习笔记(六五):安全和权限(2):权限和自定义权限

目录(?)[-] 进程边界 声明和使用权限 AndroidManifestxml的许可设置 自定义权限 运行安全通过两个层面进行保护.进程层面:不同应用运行在不同的进程,每个应用有独自的user ID:在操作层面,Android定义了所需保护的功能和资源,如果应用需要访问这些信息,必须在AndroidManifest.xml文件中请求许可,应用可以有自定义的许可. 进程边界 每个应用的userID不同,使得各个进程之间存在隔离的边界,防止应用直接获取其他应用的数据,需要通过content pro

DRF认证、自定义认证和权限、自定义权限

源码分析 """ 1)APIView的dispath(self, request, *args, **kwargs) 2)dispath方法内 self.initial(request, *args, **kwargs) 进入三大认证 # 认证组件:校验用户 - 游客.合法用户.非法用户 # 游客:代表校验通过,直接进入下一步校验(权限校验) # 合法用户:代表校验通过,将用户存储在request.user中,再进入下一步校验(权限校验) # 非法用户:代表校验失败,抛出异常

自定义权限模块

from rest_framework.permissions import BasePermission class CustomPermission(BasePermission): def has_permission(self, request, view): - 权限模块工作原理 1)继承BasePermission类,重写has_permission方法 2)权限规则(has_permission方法实现体): 返回True,代表有权限 返回False,代表无权限 - request