Drf从入门到精通十(基于JWT自定义认证类、排序与过滤源码分析、RBAC介绍与使用、SimpleUI介绍与使用)

一、基于JWT自定义认证类

上篇文章我们刚讲完基于Session的JWT认证类 那我们现在研究研究怎样实现JWT的认证类 就从它的认证类下手JSONWebTokenAuthentication
点击进去发现没有authenticate方法 但是它继承了BaseJSONWebTokenAuthentication 再进去看第一个就是我们要找的authenticate方法了

源码展示

class BaseJSONWebTokenAuthentication(BaseAuthentication):
    def authenticate(self, request):
        jwt_value = self.get_jwt_value(request)			# 获取前端传入的信息request
        if jwt_value is None:							# 判断是否有值 
            return None

        try:		# 最核心的就是JWT的核心代码了
            payload = jwt_decode_handler(jwt_value)		# 解码信息获取Token 去验证
        except jwt.ExpiredSignature:
            msg = _('Signature has expired.')			# 签名时间过期超时
            raise exceptions.AuthenticationFailed(msg)
        except jwt.DecodeError:
            msg = _('Error decoding signature.')		# 错误的解码方式签名
            raise exceptions.AuthenticationFailed(msg)
        except jwt.InvalidTokenError:					# 认证失败
            raise exceptions.AuthenticationFailed()

        user = self.authenticate_credentials(payload)	# 判断是否跟库里面的用户一致 返回用户

        return (user, jwt_value)						# 返回当前登录用户 与token

我们看懂了这个源码之后我们就知道了怎样重写JWT认证类了 重写它的authenticate即可

class Base(BaseAuthentication):
    def authenticate(self, request):
        try:
            rest_token = request.META.get('HTTP_AUTHORIZATION')  # 获取传入的Token
            jwt_name, token = rest_token.split(' ')     # 取出token中的空格
            payload = jwt_decode_handler(token)  # 获取数据库的Token
        except jwt.ExpiredSignature:
            msg = ('签名时间已经过期啦!!!')
            raise exceptions.AuthenticationFailed(msg)
        except jwt.DecodeError:
            msg = ('错误的解放方式')
            raise exceptions.AuthenticationFailed(msg)
        except jwt.InvalidTokenError:
            raise exceptions.AuthenticationFailed()
        user = UserInfo.objects.filter(pk=payload.get('user_id')).first()
        return user, token

	'''
		也可以直接返回Payload就不用走数据库查询 加快效率
		return (payload, token)
		
		配置视图认证类
			class JwtView(APIView):
    			authentication_classes = [Base, ]
	'''

在这里插入图片描述

二、排序和过滤源码分析

首先回想我们的排序与过滤 想使用他们两个必须继承GenericAPIView + ListModelMixin及其子类 排序类OrderingFiler
只要在视图类中配置filter_backends、filterset_fields&search_fields就可以实现过滤和排序了 内置的过滤类SearchFilter
Django-filter 自定义写一个类 继承BaseFilterBackend 重写filter_queryset 返回的queryset对象 就是过滤或排序后的数据了
再次我们使用排序与过滤的时候只会在获取信息的时候才会用到 所以我们进到源码中查找list方法就好了

def list(self, request, *args, **kwargs):
        # self.get_queryset()所有数据,经过了self.filter_queryset返回了qs
        # self.filter_queryset完成的过滤
        queryset = self.filter_queryset(self.get_queryset())
        # 如果有分页,走的分页----》视图类中配置了分页类
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
	   # 如果没有分页,走正常的序列化,返回
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    
    
    -self.filter_queryset完成了过滤,当前在视图类中,self是视图类的对象,去视图类中找没找到,去父类---》GenericAPIView---》filter_queryset
    
        def filter_queryset(self, queryset):
            for backend in list(self.filter_backends):
                queryset = backend().filter_queryset(self.request, queryset, self)
            return queryset
        
 '''
	-写的过滤类要重写filter_queryset,返回qs(过滤或排序后)对象
    -后期如果不写过滤类,只要在视图类中重写filter_queryset,在里面实现过滤也可以
 '''

三、RBAC的介绍与使用

什么是RBAC?

  • RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
  • RBAC权限管理的模式,最适合公司内部的管理系统,不适合对外互联网用户的系统
  • Django的后台管理Admin就自带了RBAC的权限,通过Auth模块实现的,比普通RBAC更高级一些就是我们迁移表模型自动创建的
  • 很多公司写后台管理使用Django,使用Django的Admin二次开发,不用写权限了,快速加功能即可
	 1. auth_user 					用户表
	 2. auth_group					角色表
	 3. auth_permission 			权限表
	 4. auth_user_groups 			用户与角色中间表
	 5. auth_group_permissions 		角色与权限中间表
	 6. auth_user_user_permissions 	用户与权限中间表

在这里插入图片描述

快速体验Django Admin的RBAC的权限控制

创建好表模型
	class UserInfo(models.Model):
	    username = models.CharField(max_length=32, verbose_name='名称')
	    password = models.CharField(max_length=32, verbose_name='密码')
	
	    class Meta:
	        verbose_name_plural = '用户信息表'
	
	    def __str__(self):
	        return self.username

通过createsuperuser进入后台新建用户以及其他信息 可以创建组表示这一组里面的角色有什么权限
在这里插入图片描述
在这里插入图片描述

1)ACL、RBAC、ABAC(PBAC、CBAC)权限控制介绍

  • ACL(Access Control List,访问控制列表)

     将用户或组等使用者直接与对象的权限对接
     比如张三只有看抖音发抖音的权限 没有开直播的权限 交给第三张中间表来控制权限授予用户的角色
    
  • RBAC(Role-Based Access Control,基于角色的访问控制)

     将用户与角色对接 然后角色与对象的权限对接 就是跟Django的用法一样 本质就是RBAC+ACL 公司用的比较多
    
  • ABAC(Attribute-Based Access Control,基于属性的访问控制)

     ABAC(Attribute-Based Access Control,基于属性的访问控制)又称为PBAC(Policy-Based Access Control,基于策略的访问控制)
     CBAC(Claims-Based Access Control,基于声明的访问控制),传统的ACL RBAC的架构是 {subject action object},而ABAC的架构是
     {subject action object contextual},且为他们添加了parameter(参数)----简单说就是给单个权限再加上属性双重认证的感觉
    

2)Casbin模块

这个模块支持个个语言 专门做权限控制的模块(ACL RBAC ABAC) 方便我们快速做权限控制
安装Casbin

pip install casbin

根据casbin的要求需要创建两个文件一个model 一个policy 做一个最简单的ACL模型 就可以快速测试出有没有权限了
Casbin网站:https://docs.casbin.cn/zh/docs/supported-models

创建自定义py文件

import casbin

e = casbin.Enforcer("./model.conf", "./policy.csv")

sub = "alice"  # 想要访问资源的用户
obj = "data1"  # 将要被访问的资源
act = "read"  # 用户对资源进行的操作

if e.enforce(sub, obj, act):
    # 允许alice读取data1
    print('有权限')
else:
    # 拒绝请求,抛出异常
    print('没有权限')

model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

policy.csv

p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write
g, alice, data2_admin

在这里插入图片描述

四、后台管理Simple UI的介绍与使用

Django-admin自带了权限控制 但是是前后端混合的 我们可以去二次开发 开发出公司内部的自动化运行 自动化测试 人事管理系统
但是他的界面样子UI不好看 所以我们现在就要对django-admin进行美化有两个主流 Xadmin(已过时) SimpleUI(正红)

或者是基于Drf+Vue 自己写前后端分离的权限管理 在Go源里面使用Go-Vue-Admin

安装

pip install django-simpleui

用pip或者源码方式安装simpleui后 在自己项目的settings.py文件中INSTALLED_APPS的第一行加入

INSTALLED_APPS = [		
    'simpleui',			# 一定要注册在第一行!!!
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework',
]

然后这个时候访问我们的admin接口就会得到一个全新的admin系统 然后还可以进行美化修改主题以及字体大小…
SimpleUI新手快速上手指南网站:https://simpleui.72wo.com/docs/simpleui/quick.html#%E7%9B%AE%E5%BD%95
在这里插入图片描述

自定义左侧的菜单栏 settings.py

import time

SIMPLEUI_CONFIG = {
    'system_keep': False,
    'menu_display': ['Simpleui', '信息管理',  '权限认证', '多级菜单测试', '动态菜单测试'],  # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
    'dynamic': True,  # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
    'menus': [{
        'name': 'Simpleui',
        'icon': 'fas fa-code',
        'url': 'https://blog.csdn.net/MeiJin_',
        # 浏览器新标签中打开
        'newTab': True,
    }, {
        'app': 'app01',
        'name': '信息管理',
        'icon': 'fas fa-code',
        'models': [
            {
                'name': '用户信息',
                'url': 'app01/userinfo/',
                'icon': 'far fa-surprise'
            },
            {
                'name': '书籍信息',
                'url': 'app01/books/',
                'icon': 'far fa-surprise'
            },
            {
                'name': '出版社信息',
                'url': 'app01/publish/',
                'icon': 'far fa-surprise'
            },
        ]
    },
        {
            'app': 'auth',
            'name': '权限认证',
            'icon': 'fas fa-user-shield',
            'models': [{
                'name': '用户',
                'icon': 'fa fa-user',
                'url': 'auth/user/'
            }]
        }, {
            # 自2021.02.01+ 支持多级菜单,models 为子菜单名
            'name': '多级菜单测试',
            'icon': 'fa fa-file',
            # 二级菜单
            'models': [{
                'name': 'Baidu',
                'icon': 'far fa-surprise',
                # 第三级菜单 ,
                'models': [
                    {
                        'name': '爱奇艺',
                        'url': 'https://www.iqiyi.com/dianshiju/'
                        # 第四级就不支持了,element只支持了3级
                    }, {
                        'name': '百度问答',
                        'icon': 'far fa-surprise',
                        'url': 'https://zhidao.baidu.com/'
                    }
                ]
            }, {
                'name': '内网穿透',
                'url': 'https://www.wezoz.com',
                'icon': 'fab fa-github'
            }]
        }, {
            'name': '动态菜单测试',
            'icon': 'fa fa-desktop',
            'models': [{
                'name': time.time(),
                'url': 'http://baidu.com',
                'icon': 'far fa-surprise'
            }]
        }]
}

自定义按钮 admin.py

@admin.register(Books)
class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'price', 'author')		# 字段必须是模型中存在的字段
    #
    # 增加自定义按钮
    actions = ['make_copy',]		# 一定要与下方的函数名对称

    def make_copy(self, request, queryset):
        print('我是自定义的按钮')			# 点击按钮要执行的事件
    #
    # # 显示的文本,与django admin一致
    make_copy.short_description = '测试按钮'
    # # icon,参考element-ui icon与https://fontawesome.com
    make_copy.icon = 'fas fa-audio-description'
    #
    # # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
    make_copy.type = 'danger'
    #
    # # 给按钮追加自定义的颜色
    # custom_button.style = 'color:black;'
	
	make_copy.confirm = '你是否执意要点击这个按钮?'     # 弹窗提示按钮

在这里插入图片描述

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 我可以帮你分析一下这个项目,并为你提供一些建议。首先,你需要根据 vue 和 drf 的文档,熟悉这两个技术的使用方式。然后,需要设计一个前端页面,使用 vue 技术来实现。接着,你需要利用 drf 来构建一个 RESTful API,用来实现注册和登录功能。最后,你可以将前端与后端连接起来,完成注册和登录功能。 ### 回答2: 基于Vue和DRF的前后端分离注册登录项目设计可分为以下几个步骤: 1. 前端项目搭建:使用Vue CLI等工具搭建一个Vue项目。 2. 前端注册页面设计:创建一个注册页面,包括输入用户名、密码、确认密码等表单项,并添加表单验证功能。 3. 前端登录页面设计:创建一个登录页面,包括输入用户名、密码等表单项,并添加表单验证功能。 4. 前端与后端交互:使用Axios等工具发送注册和登录请求至后端API,并处理接口返回的数据。 5. 后端项目搭建:使用DjangoDRF搭建一个后端项目。 6. 后端用户模型设计:创建一个用户模型,并添加字段如用户名、密码等。 7. 后端注册API设计:创建一个注册API,接收前端传递的用户名和密码等参数,使用Django的用户模型创建用户,并返回注册成功的信息。 8. 后端登录API设计:创建一个登录API,接收前端传递的用户名和密码等参数,验证用户信息,并返回登录成功的信息和用户的认证token。 9. 前端登录状态管理:在前端使用Vuex等工具进行登录状态管理,保存用户的认证token,并在每次请求时将token作为请求的Header。 10. 前端路由配置:配置前端路由,通过路由守卫判断用户是否已登录,未登录则重定向至登录页面。 通过以上步骤的设计,实现了一个基于Vue和DRF的前后端分离的注册登录项目。前端负责提供注册和登录的页面,与后端通过API进行交互并管理用户登录状态。后端则负责验证用户信息、创建用户和返回认证信息等操作。 ### 回答3: 基于Vue和DRF设计一个前后端分离的注册登录项目是一个常见的实践项目。下面是一个简单的实现示例: 1. 前端设计: 在前端使用Vue框架,先创建一个Vue实例,并引入需要的相关依赖库,如axios用于发送与接收HTTP请求。 创建两个组件,一个用于注册,另一个用于登录。在组件中定义输入框和按钮,并绑定相应的方法和数据。 注册组件:包括用户名和密码的输入框以及注册按钮。 登录组件:包括用户名和密码的输入框以及登录按钮。 在注册组件的注册按钮点击事件中,使用axios发送POST请求到后端API,将输入的用户名和密码作为参数传递给后端,完成注册操作。 在登录组件的登录按钮点击事件中,同样使用axios发送POST请求到后端API,传递输入的用户名和密码,后端返回登录验证的结果。 2. 后端设计: 使用DRFDjango REST framework)构建后端API。创建用户模型,包含用户名和密码字段,并实现注册和登录视图。 注册视图中,接收前端传递过来的用户名和密码参数,先检查用户名是否已存在,若存在则返回相应的错误信息,否则创建用户并保存到数据库中。 登录视图中,接收前端传递过来的用户名和密码参数,根据用户名在数据库中查询用户信息并验证密码是否正确,返回登录验证结果。 为了实现与前端的数据交互,需要配置CORS(跨源资源共享)中间件,允许前端跨域请求后端API。 3. 前后端交互: 前后端交互通过HTTP请求完成,前端使用axios发送POST请求到后端API,并将参数作为请求体的一部分。后端接收到请求后,解析请求体中的参数,做出相应的处理,并返回结果。 通过以上设计,前端可以通过注册组件完成用户注册,后端接收到请求并保存用户信息。前端可以通过登录组件完成用户登录,后端验证用户信息后返回登录验证结果。这样就实现了一个简单的前后端分离的注册登录项目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoisMay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值