首页 > 编程语言 >DRF的权限组件(源码分析)

DRF的权限组件(源码分析)

时间:2023-04-21 15:38:06浏览次数:41  
标签:return models request token 源码 组件 import def DRF

DRF的权限组件(源码分析)

1. 创建用户表

from django.db import models


# Create your models here.
class UserInfo(models.Model):
    role_choice = ((1, 'CEO'), (2, 'CTO'), (3, 'CFO'))
    role = models.SmallIntegerField(verbose_name='类型', choices=role_choice, default=1)
    username = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=32)
    token = models.CharField(verbose_name='TOKEN', max_length=64, null=True, blank=True)

2. 自定义权限类

from rest_framework.permissions import BasePermission


class PermissionA(BasePermission):
    message = {'code': 1003, 'data': '无权访问'}

    def has_permission(self, request, view):
        if request.user.role == 2:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        return True

3. 视图函数中添加认证

  • 局部配置(views.py)
class UserView(APIView):
    permission_classes = [PermissionA, ]  # role权限
    
    def get(self, request):
        ...
  • 全局配置(settings.py)
REST_FRAMEWORK = {
    # 权限
    "DEFAULT_PERMISSION_CLASSES": ["app01.permission.PermissionA", ]
}

4. 多个权限类

当开发过程中需要用户同时具备多个权限(缺一不可)时,可以用多个权限类来实现。

权限组件内部处理机制:按照列表的顺序逐一执行 has_permission 方法,如果返回True,则继续执行后续的权限类;如果返回None或False,则抛出权限异常并停止后续权限类的执行。

# models.py

from django.db import models


class Role(models.Model):
    """ 角色表 """
    title = models.CharField(verbose_name="名称", max_length=32)


class UserInfo(models.Model):
    """ 用户表 """
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)
    token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)

    roles = models.ManyToManyField(verbose_name="角色", to="Role")
# urls.py

from django.urls import path, re_path, include
from app01 import views

urlpatterns = [
    path('api/auth/', views.AuthView.as_view()),
    path('api/order/', views.OrderView.as_view()),
]

# views.py

import uuid
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import AuthenticationFailed

from app01 import models


class AuthView(APIView):
    """ 用户登录认证 """

    def post(self, request, *args, **kwargs):
        print(request.data)  # {"username": "wupeiqi", "password": "123"}
        username = request.data.get('username')
        password = request.data.get('password')

        user_object = models.UserInfo.objects.filter(username=username, password=password).first()
        if not user_object:
            return Response({"code": 1000, "data": "用户名或密码错误"})

        token = str(uuid.uuid4())

        user_object.token = token
        user_object.save()

        return Response({"code": 0, "data": {"token": token, "name": username}})


class TokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.query_params.get("token")
        if not token:
            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})
        user_object = models.UserInfo.objects.filter(token=token).first()
        if not user_object:
            raise AuthenticationFailed({"code": 1002, "data": "认证失败"})
        return user_object, token

    def authenticate_header(self, request):
        return 'Bearer realm="API"'


class PermissionA(BasePermission):
    message = {"code": 1003, 'data': "无权访问"}

    def has_permission(self, request, view):
        exists = request.user.roles.filter(title="员工").exists()
        if exists:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        return True


class PermissionB(BasePermission):
    message = {"code": 1003, 'data': "无权访问"}

    def has_permission(self, request, view):
        exists = request.user.roles.filter(title="主管").exists()
        if exists:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        return True

class OrderView(APIView):
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [PermissionA, PermissionA]

    def get(self, request, *args, **kwargs):
        return Response({"code": 0, "data": {"user": None, 'list': [1, 2, 3]}})


class PayView(APIView):
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [PermissionA, ]

    def get(self, request, *args, **kwargs):
        return Response({"code": 0, "data": "数据..."})

5. 关于has_object_permission

后期补充...

6. 源码分析

第三步前面的部分执行流程和前两篇文章是一样的. 这里就不过多赘述了

标签:return,models,request,token,源码,组件,import,def,DRF
From: https://www.cnblogs.com/huxiaofeng1029/p/17340501.html

相关文章

  • Spring源码系列(补充):详解ApplicationContext
    前言在之前的文章中,我们已经对Spring源码中的一些核心概念进行了分析。由于篇幅限制,我们并没有详细解释ApplicationContext类所继承的父接口及其作用。因此,本文将单独为ApplicationContext进行详细说明,包括其继承的父接口及其作用。ApplicationContext父接口MessageSource大家......
  • 在idea中查看源码时 download source failed的处理办法
    检查ideamaven配置切换路径BuildTools->Maven->Importing勾选前两个执行maven命令:mvndependency:resolve-Dclassifier=sources执行完后,再次打开源码类就能看到源码了。......
  • xHook 源码解析
    xHook是爱奇艺开源的一个PLTHook框架项目地址:https://github.com/iqiyi/xHook该项目实现了PTL/GOTHookPTLhook的本质是修改内存中,PLT表对应的值,来实现跳转到自定义函数的.got和.plt它们的具体含义。TheGlobalOffsetTable(GOT)。简单来说就是在数据段的地址表......
  • element-ui 的 table 组件 无法设置行高的问题?
    element-ui的table组件无法设置行高的问题因为需要改变table组件的行高;试了好多方法;包括官方文档提供的方法cell-style,cell-class-name,虽然能加上样式但是没有效果,不知道啥原因,最后发现td下面有个class为cell的div,于是修改如下.cell{max-height:94px!important;ove......
  • vue2源码-十一、Vue的生命周期
    Vue的生命周期钩子函数是如何实现?内部利用一个发布订阅模式,将用户写的钩子维护成一个数组,后续依次调用hooks。主要靠的是mergerOptions方法有哪些?引用自https://vue3js.cn/interview/vue/lifecycle.html#%E4%BA%8C%E3%80%81%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E6%9C%......
  • Flutter组件化开发方案
    原文地址zhuanlan.zhihu.comFlutter组件化开发方案残枫cps​目录收起前言1.存在的问题2.改进点3.从PlatformChannel说起4.FlutterPlugin5.Pub6.PrivatePub7.Flutter工程结构8.开发流程总结原文地址juejin.cn前言前面讲了Flutter和Native的混合开发模式,Flutter作为......
  • vue3 源码
     这文章写的很好 Compiler模块:编译模板系统。主要职责是将template编译成虚拟节点。Runtime模块:也可以称之为Renderer模块,真正负责渲染的模块。主要职责是将虚拟节点渲染成真实元素,然后显示到浏览器上。Reactivity模块:响应式系统。主要职责是监听响应式的数据,然后通过di......
  • 【快应用】list-item组件的正确隐藏
    【关键词】list组件 if/show 【问题背景】list组件中给list-item使用show属性后,再设置为false后,会有一个空白位置留出,感觉位置好像还是被占据着,这种情形我们该如何处理?如下图所示:​​ 【问题原因】引擎list组件的实现就是这样的,show为false时只是将控件设置为隐藏,dom......
  • 下载Apache软件基金的软件和项目(Hadoop相关组件)
    一、下载Hadoop相关组件,可以到Apache软件基金的资源目录:Apache分发目录地址:https://dlcdn.apache.org/   二、下载软件方法一:在页面中找到需要下载的软件目录,点击进去,选择对应的版本就可以直接下载。方法二:在上面的地址栏中直接加上对应的组件名称,进入后选择对应的版......
  • 华为云 OpenTiny 跨端、跨框架企业级开源组件库项目落地实践直播即将开启!
    大家好,我是Kagol,公众号:前端开源星球。“你们这个产品怎么只能在电脑上适配呀?我想在手机上看都不行,太麻烦了!!”“你们这个产品看起来太简单了,我想要@@功能,你们这都不能实现吗?”“你们这个产品到底安全不安全呀,不会填一点信息然后全给我泄露出去了吧!”我们前端开发同学在工作过......