Django rest framework 权限操作(源码分析二)

知识回顾

这一篇是基于上一篇写的,上一篇谢了认证的具体流程,看懂了上一篇这一篇才能看懂,

当用户访问是 首先执行dispatch函数,当执行当第二部时:

   #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制
            self.initial(request, *args, **kwargs)

进入到initial方法:

 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.3处理权限信息
        self.check_permissions(request)

下面 开始 权限的具体分析:

进入到check_permissions函数中

 #检查权限
    def check_permissions(self, request):
        """
        Check if the request should be permitted.
        Raises an appropriate exception if the request is not permitted.
        """
        #elf.get_permissions()得到的是一个权限对象列表
        for permission in self.get_permissions():
            #在自定义的Permission中has_permission方法是必须要有的
            #判断当前has_permission返回的是True,False,还是抛出异常
            #如果是True则表示权限通过,False执行下面代码
            if not permission.has_permission(request, self):
                #为False的话则抛出异常,当然这个异常返回的提示信息是英文的,如果我们想让他显示我们自定义的提示信息
                #我们重写permission_denied方法即可
                self.permission_denied(
                    #从自定义的Permission类中获取message(权限错误提示信息),一般自定义的话都建议写上,如果没有则为默认的(英文提示)
                    request, message=getattr(permission, ‘message‘, None)
                )

查看permission_denied方法(如果has_permission返回True则不执行该方法)

 def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """
        if request.authenticators and not request.successful_authenticator:
            #没有登录提示的错误信息
            raise exceptions.NotAuthenticated()
        #一般是登陆了但是没有权限提示
        raise exceptions.PermissionDenied(detail=message)

举例:

from django.db import models

# Create your models here.
class Userinfo(models.Model):
    name=models.CharField(max_length=32,verbose_name=‘用户名‘)
    pwd=models.CharField(max_length=32,verbose_name=‘密码‘)
    token=models.CharField(max_length=64,null=True)

    def __str__(self):
        return self.name

models

urlpatterns = [
    url(r‘^p/‘, app02_views.Pview.as_view()),
    url(r‘^mp/‘, app02_views.Aview.as_view()),
    url(r‘^jp/‘, app02_views.Jview.as_view()),
]

urls

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import exceptions

from app01 import models
# Create your views here.

class MyAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token=request.query_params.get(‘token‘)
        user=models.Userinfo.objects.filter(token=token).first()
        if user:
            return (user.name,user)
        return None

class MyPermission(object):
    message = ‘登录才可以访问‘
    def has_permission(self,request, view):
        if request.user:
            return True
        return False

class AdminPermission(object):
    message = ‘会员才可以访问‘
    def has_permission(self,request,view):
        if request.user==‘ctz‘:
            return True
        return False

class Pview(APIView):
    ‘‘‘
    所有人都可以看
    ‘‘‘
    authentication_classes = [MyAuthentication,]
    permission_classes = []
    def get(self,request):
        return Response(‘图片列表‘)
    def post(self,request):
        pass

class Aview(APIView):
    ‘‘‘
    登录的人可以看
    ‘‘‘
    authentication_classes = [MyAuthentication,]
    permission_classes = [MyPermission,]
    def get(self,request):
        return Response(‘美国电影列表‘)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(‘无权访问‘)
        raise exceptions.PermissionDenied(detail=message)

class Jview(APIView):
    ‘‘‘
    会员才可以看
    ‘‘‘
    authentication_classes = [MyAuthentication,]
    permission_classes = [MyPermission,AdminPermission,]
    def get(self,request):
        return Response(‘日本电影列表‘)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(‘无权访问‘)
        raise exceptions.PermissionDenied(detail=message)

Views

上面的是局部的只能在当前类中可以用,如果想在全局中用:只需要在settings中配置即可:

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import exceptions

from app02.utils import MyPermission
#
#
from app01 import models
# # Create your views here.
#
# class MyAuthentication(BaseAuthentication):
#
#     def authenticate(self, request):
#         token=request.query_params.get(‘token‘)
#         user=models.Userinfo.objects.filter(token=token).first()
#         if user:
#             return (user.name,user)
#         return None
#
# class MyPermission(object):
#     message = ‘登录才可以访问‘
#     def has_permission(self,request, view):
#         if request.user:
#             return True
#         return False
#
# class AdminPermission(object):
#     message = ‘会员才可以访问‘
#     def has_permission(self,request,view):
#         if request.user==‘ctz‘:
#             return True
#         return False

class Pview(APIView):
    ‘‘‘
    所有人都可以看
    ‘‘‘

    permission_classes = []
    def get(self,request):
        return Response(‘图片列表‘)
    def post(self,request):
        pass

class Aview(APIView):
    ‘‘‘
    登录的人可以看
    ‘‘‘
  #  authentication_classes = [MyAuthentication,]
    permission_classes = [MyPermission,]
    def get(self,request):
        return Response(‘美国电影列表‘)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(‘无权访问‘)
        raise exceptions.PermissionDenied(detail=message)

class Jview(APIView):
    ‘‘‘
    会员才可以看
    ‘‘‘
    # authentication_classes = [MyAuthentication,]
    # permission_classes = [MyPermission,AdminPermission,]
    def get(self,request):
        return Response(‘日本电影列表‘)
    def post(self,request):
        pass

    def permission_denied(self, request, message=None):
        """
        If request is not permitted, determine what kind of exception to raise.
        """

        if request.authenticators and not request.successful_authenticator:
            raise exceptions.NotAuthenticated(‘无权访问‘)
        raise exceptions.PermissionDenied(detail=message)

Views

from django.shortcuts import render

from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import exceptions
from rest_framework.exceptions import APIException

from app01 import models
# Create your views here.

class MyAuthentication(BaseAuthentication):

    def authenticate(self, request):
        token=request.query_params.get(‘token‘)
        user=models.Userinfo.objects.filter(token=token).first()
        if user:
            return (user.name,user)
        return None

class MyPermission(object):
    message = ‘登录才可以访问‘
    def has_permission(self,request, view):
        if request.user:
            return True
        return False

class AdminPermission(object):
    message = ‘会员才可以访问‘
    def has_permission(self,request,view):
        if request.user==‘ctz‘:
            return True
        return False

utils

REST_FRAMEWORK = {
    ‘UNAUTHENTICATED_USER‘: None,
    ‘UNAUTHENTICATED_TOKEN‘: None,
    "DEFAULT_AUTHENTICATION_CLASSES": [
      # "app01.utils.MyAuthentication",
        "app02.utils.MyAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES":[
       "app02.utils.MyPermission",
       "app02.utils.AdminPermission",
    ],
}

settings

原文地址:https://www.cnblogs.com/mjc69213/p/9937349.html

时间: 2024-08-03 07:44:43

Django rest framework 权限操作(源码分析二)的相关文章

Django REST framework —— 权限组件源码分析

在上一篇文章中我们已经分析了认证组件源码,我们再来看看权限组件的源码,权限组件相对容易,因为只需要返回True 和False即可 代码 1 class ShoppingCarView(ViewSetMixin, APIView): 2 permission_classes = [MyPermission, ] 3 def list(self,request, *args, **kwargs): 4 """ 5 查看购物车信息 6 :param args: 7 :param k

Django——基于类的视图源码分析 二

源码分析 抽象类和常用视图(base.py) 这个文件包含视图的顶级抽象类(View),基于模板的工具类(TemplateResponseMixin),模板视图(TemplateView)和重定向视图(RedirectView). View及View的执行顺序 View是所有基于类的视图的基类.仅实现了一些基本的方法和必要的检查工作.其中最重要的是dispatch方法.再次方法中,根据HTTP请求 中的method参数,调用相应的同名处理函数.这里留下了一个口子,后续的类需要根据自己的情况来填补

django的RBAC认证z;自定义auth_user表;认证组件权限组件源码分析;认证组件;权限组件

一 RBAC 1.RBAC:全称(Role-Based Access Control):指的是基于用户权限访问控制的认证. 2.Django框架采用的是RBAC认证规则,RBAC认证规则通常会分为:三表规则,五表规则:Django采用的是六表规则. # 三表:用户表.角色表.权限表# 五表:用户表.角色表.权限表.用户角色关系表.角色权限关系表# 六表:用户表.角色表.权限表.用户角色关系表.角色权限关系表.用户权限关系表 3.在Django中六表之间是都是多对多的关系,可通过下面字段跨表访问

Django的settings文件部分源码分析

Django的settings文件部分源码分析 在编写Django项目的过程中, 其中一个非常强大的功能就是我们可以在settings文件配置许多选项来完成我们预期的功能, 并且这些配置还必须大写, 否则就不会生效. 此外, Django自身还有一套更详细的配置, 那Django是如何做到用户配置了相关配置就使用用户的配置, 否则就使用自己默认的配置. 带着这样的疑问, 去查看了用户配置项相关的源码部分. 过程分析 首先启动Django项目, 一般Django都是通过python manage.

netty 源码分析二

以服务端启动,接收客户端连接整个过程为例分析, 简略分为 五个过程: 1.NioServerSocketChannel 管道生成, 2.NioServerSocketChannel 管道完成初始化, 3.NioServerSocketChannel注册至Selector选择器, 4.NioServerSocketChannel管道绑定到指定端口,启动服务 5.NioServerSocketChannel接受客户端的连接,进行相应IO操作 Ps:netty内部过程远比这复杂,简略记录下方便以后回忆

JAVA Collection 源码分析(二)之SubList

昨天我们分析了ArrayList的源码,我们可以看到,在其中还有一个类,名为SubList,其继承了AbstractList. // AbstractList类型的引用,所有继承了AbstractList都可以传进来 private final AbstractList<E> parent; // 这个是其实就是parent的偏移量,从parent中的第几个元素开始的 private final int parentOffset; private final int offset; int s

[Android]Volley源码分析(二)Cache

Cache作为Volley最为核心的一部分,Volley花了重彩来实现它.本章我们顺着Volley的源码思路往下,来看下Volley对Cache的处理逻辑. 我们回想一下昨天的简单代码,我们的入口是从构造一个Request队列开始的,而我们并不直接调用new来构造,而是将控制权反转给Volley这个静态工厂来构造. com.android.volley.toolbox.Volley: public static RequestQueue newRequestQueue(Context conte

哇!板球 源码分析二

游戏主页面布局 创建屏下Score标签 pLabel = CCLabelTTF::create("Score", "Arial", TITLE_FONT_SIZE); //分数标签 //设置标签字体的颜色 pLabel->setColor (ccc3(0, 0, 0)); //设置文本标签的位置 pLabel->setPosition ( ccp ( SCORE_X, //X坐标 SCORE_Y //Y坐标 ) ); //将文本标签添加到布景中 this

baksmali和smali源码分析(二)

这一节,主要介绍一下 baksmali代码的框架. 我们经常在反编译android apk包的时候使用apktool这个工具,其实本身这个工具里面对于dex文件解析和重新生成就是使用的baksmali 和smali这两个jar包其中 baksmali是将 dex文件转换成便于阅读的smali文件的,具体使用命令如下:java -jar baksmali.jar classes.dex -o myout其中myout是输出的文件夹 而smali是将smali文件重新生成回 dex文件的具体使用的命