二十二、身份验证与权限
一、 准备工作
为了讲清楚身份验证与权限,我们再创建一个应用projects,设计模型如下:
class Project(models.Model):name = models.CharField('项目名称', max_length=20, help_text='项目名称')desc = models.CharField('项目描述', max_length=200, help_text='项目描述', null=True, blank=True)leader = models.ForeignKey('auth.User', verbose_name='项目负责人', on_delete=models.SET_NULL, null=True, help_text='项目负责人')c_time = models.DateTimeField('创建时间', auto_now_add=True)
编写序列化器
from rest_framework import serializers
from .models import Projectclass ProjectSerializer(serializers.ModelSerializer):class Meta:model = Projectfields = '__all__'
编写视图集
class ProjectViewSet(ModelViewSet):queryset = Project.objects.all()serializer_class = ProjectSerializer
配置url
router = DefaultRouter()
router.register(r'projects', views.ProjectViewSet)
urlpatterns = [...path('', include(router.urls))
]
目前,我们的API对谁可以编辑或删除项目没有任何限制。我们希望有一些更高级的行为,以确保:
- 项目总是与创建者相关联。
- 只有经过身份验证的用户才能创建项目。
- 只有项目的创建者才能更新或删除它。
- 未经身份验证的请求应该具有完全只读访问权限。
创建用户方法一:
我们需要先创建一个超级管理员。不然我们项目Project模型中leader外键关联的auth.User表没有数据,创建Project的时候选不到数据。
# 创建超级管理员
python manage.py createsuperuser
创建用户方法二:
有了超级用户可以访问网址去创建,输入你刚才创建的超级管理员
因为考虑后面需要测普通管理员的权限,我们去把其中一个超级管理员的权限卸掉。
此时我们去创建一个项目负责人为test的项目。
因为我们登录着,所以我们可视化api右上角才显示登录的状态。
这个时候我们访问 http://127.0.0.1:8000/admin/auth/user/ 退出登录,再看下drf可视化的api右上角就不展示登录的用户名。
此时就是一个匿名的状态。
那么此时我去做修改或者添加的操作,能执行成功吗?当然可以。
因为你当前写的跟用户权限没有任何关系,谁都可以去操作修改、删除、添加等一系列的操作。
那么我们现在就要做2件事情:
1. 谁创建这个项目,这个项目就跟谁关联(好比我去超市买东西,扣的是我的钱而不是别人的钱)。
2. 登录后方有权限去创建、修改删除等一系列操作。
二、关联项目与用户
现在我们可以创建项目,并手动选择对应的用户与项目进行关联。但是在某些场景下这可能不是你想要的,比如谁创建项目就把谁与创建的项目进行关联。
那么用户就不能再作为序列化表示的一部分发送,而是传入请求的一个属性。django会将当前用户对象设置到request.user
属性上,它是在中间件AuthenticationMiddleware
中完成的。
我们首先修改项目的序列化器,将leader
字段修改为只读,并显示用户的用户名。
方法一:
leader = serializers.ReadOnlyField(source='leader.username')
source
参数控制哪个属性用于填充字段,并可以指向序列化实例上的任何属性。它也可以采用上面所示的句点符, 在这种情况下,它将遍历给定的属性, 与Django的模板语言使用的方式类似。
ReadOnlyField
始终是只读的,并将用于序列化表示,但当模型实例被反序列化时,将不会用于更新它们。
方法二:
然后再重写项目视图上的perform_create()
方法,修改保存实例保存的方式,处理隐式传入请求或者请求URL中的任何信息,这里我们给项目关联当前用户。
在ProjectViewSet
视图集上,添加以下方法:
def perform_create(self, serializer):serializer.save(leader=self.request.user)
三、添加登录功能
此时创建项目你会发现报错,这是因为,django在未做身份验证的请求的user
属性上绑定了一个AnonymousUser
对象。我们需要能够以用户身份登录。
通过编辑根urls.py
文件中的URLconf,我们可以添加一个login视图来与可浏览的API一起使用。
在文件的末尾,添加一个模式,以包含可浏览API的登录和注销视图。
urlpatterns += [path('auth/', include('rest_framework.urls')),
]
模式的'auth/'
部分实际上可以是你想使用的任何URL。
现在,如果你再次打开浏览器并刷新页面,你会在页面的右上角看到一个“Login”
链接。登录之前创建的用户,你将能够再次创建项目。
四、向视图添加权限
现在我们希望确保只有经过身份验证的用户才能创建、更新和删除项目。REST框架包括许多权限类,我们可以使用它们来限制谁可以访问给定的视图。在这个例子中,我们要找的是IsAuthenticatedOrReadOnly,这将确保经过身份验证的请求获得读写访问权限,而未经身份验证的请求获得只读访问权限。
首先在views模块中添加以下导入
from rest_framework import permissions
然后,将下列属性添加到ProjectListCreateView和ProjectDetailUpdateDeleteView视图类中。
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
现在退出登录,你会发现在项目列表页面的POST请求表单不见了,项目详情页的update,put
按钮也看不见了。
五、对象级权限
再创建一个用户并登录,你会发现可以对前面用户创建的项目进行编辑。
实际上,我们希望所有项目对任何人都可见,但也要确保只有创建了项目的用户才能更新或删除它。
为此,我们需要创建一个自定义的权限。
在projects应用程序中,创建一个新文件permissions.py
,编写如下代码:(咋知道咋写的,去看下别人封装好的权限是咋写的)
from rest_framework import permissionsclass IsOwnerOrReadOnly(permissions.BasePermission):"""自定义权限只允许对象的leader才能编辑它"""def has_object_permission(self, request, view, obj):if request.method in permissions.SAFE_METHODS:return Truereturn obj.leader == request.user
将它添加到ProjectDetailUpdateDeleteView
视图上
permission_classes = [permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly]
现在,再次打开浏览器,你会发现,只有当登录用户与当前代码片段的创建用户相同时,DELETE
和PUT
按钮才会出现在页面上。
六、身份验证
身份验证是将传入请求与一组识别凭证相关联的机制,例如请求携带的用户名密码,签名令牌等。然后权限之类的限制策略才可以使用这些凭证来确定是否应该允许请求。
身份验证始终在视图的最开始运行,在权限和限制检查发生之前,在任何其他代码被允许继续之前。
REST框架提供多种开箱即用的身份验证方案,后面项目实战时,我们再讨论。
七、权限验证
与身份验证,限流一起,权限决定是否应该授予或拒绝访问请求。
权限检查总是在视图的最开始运行,在任何其他代码被允许继续之前。权限检查通常会使用request.user
和request.auth
属性中的身份验证信息来确定是否应允许传入请求。
权限用于授予或拒绝不同类别的用户访问 API 的不同部分。
最简单的权限样式是允许任何经过身份验证的用户访问,而拒绝任何未经身份验证的用户访问。
八、如何确定权限
DRF中权限始终定义为权限列表。在运行视图的主体之前,检查列表中的每个权限。如果任何权限检查失败,将引发exceptions.PermissionDenied
orexceptions.NotAuthenticated
异常,并且视图的主体将不会运行。当权限检查失败时,将根据以下规则返回“403 Forbidden”或“401 Unauthorized”响应:
- 请求已成功验证,但权限被拒绝。— 将返回 HTTP 403 Forbidden 响应。
- 请求未成功通过身份验证,最高优先级的身份验证类不使用
WWW-Authenticate
标头。— 将返回 HTTP 403 Forbidden 响应。 - 请求的身份验证没有成功,并且最高优先级的身份验证类确实使用了WWW-Authenticate头。一个HTTP 401未经授权的响应,将返回一个适当的WWW-Authenticate报头。
九、对象级权限
REST 框架权限还支持对象级权限。对象级权限用于确定是否应允许用户对特定对象进行操作,该对象通常是模型实例。
对象级权限由REST框架的通用视图调用.get_object
时运行。与视图级别权限一样,也有例外。如果不允许用户对给定对象进行操作,则会引发PermissionDenied异常。
如果您正在编写自己的视图并希望强制执行对象级权限,或者覆盖了通用视图上的get_object
方法,那么您需要在视图方法中显示的调用.check_object_permissions(request, 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.views import APIViewclass ExampleView(APIView):permission_classes = [IsAuthenticated]
或者使用基于装饰器@api_view
的函数视图
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):pass
注意:直接在视图上设置权限类列表后,会忽略设置文件中配置的权限类列表。
十一、内置权限
AllowAny
IsAuthenticated
IsAdminUser
IsAuthenticatedOrReadOnly
十二、自定义权限
要实现自定义权限,请重写BasePermission并实现以下方法中的一个或两个:
●.has_permission(self, request, view)
●.has_object_permission(self, request, view, obj)
如果请求被授予访问权限,则该方法应返回True,否则返回False。
注意:对象级的has_object_permission方法只有在视图级的has_permission检查已经通过的情况下才会被调用。
如果测试失败,自定义权限将引发一个PermissionDenied异常。若要更改与异常关联的错误消息,请在自定义权限上直接实现message属性。否则,将使用PermissionDenied的default_detail属性。类似地,要更改与异常相关的代码标识符,请直接在自定义权限上实现一个code属性——否则将使用PermissionDenied的default_code属性。
from rest_framework import permissionsclass CustomerAccessPermission(permissions.BasePermission):message = 'Adding customers not allowed.'def has_permission(self, request, view):...
相关文章:
二十二、身份验证与权限
一、 准备工作 为了讲清楚身份验证与权限,我们再创建一个应用projects,设计模型如下: class Project(models.Model):name models.CharField(项目名称, max_length20, help_text项目名称)desc models.CharField(项目描述, max_length200, help_text项目…...
k8s pod 升级与回滚
当集群中的某个服务需要升级时,我们需要停止目前与该服务相关的所有pod,然后下载新版本镜像并创建新的pod。如果集群规模比较大,则这个工作变成了一个挑战,而且先全部停止然后逐步升级的方式会导致较长时间的服务不可用。kubernet…...
【Go】Go语言开发环境安装
【Go】Go语言开发环境安装 导入 安装环境:Winowds 我现在是win7安装的,与win10整体步骤是一样的,只是部分显示的时候有点差异不影响; 【名词】 编译器:先将代码编译成可执行文件,再执行; —…...
el-switch使用
效果图: 1.表格代码,给el-waitch加上change事件 <el-table-column prop"status" label"状态" align"center" width"150"> <template slot-sc…...
【算法入门】字符串基础
目录 一.字符串引言1.字符串基础二.洛谷P5734详解1.字符串相关库函数💫(1) strcpy函数 💫💫(2) strcat函数 💫💫(3)strstr函数 💫2.题…...
前端面试题 —— 浏览器原理(二)
目录 一、有哪些可能引起前端安全的问题? 二、网络劫持有哪几种,如何防范? 三、浏览器渲染进程的线程有哪些 四、僵尸进程和孤儿进程是什么? 五、为什么需要浏览器缓存? 六、对浏览器的理解 七、CSS 如何阻塞文档解析&…...
对于植物神经紊乱的治疗 中医采用辩证论治的方法
植物神经紊乱是由于心理压力过大、长期生活不规律所导致的一种疾病,这种疾病的发生往往是症状多样、涉及广泛的。当患有植物神经紊乱之后,主要的症状会以躯体化障碍为常见症状,但是很多患者还会出现情绪失控、睡眠障碍等问题。 对于植物神经紊…...
chatGPT之Python API启用上下文管理
chatGPT已经爆火一段时间了,我想大多数的开发者都在默默的在开发和测试当中,可能也是因为这个原因所以现在很难找到关于开发中遇到的一些坑或者方法和技巧。为什么别人的机器人能联想之前的语料,而你的却像个每次都只如初见的高冷机器人&…...
油田钻井实时在线监测系统
油田钻井的井下油层的压力不断变化,环境深度和压力巨大,且井下原油具有一定的流动性,实时在线压力监测是石油开采行业的难点。为更好地了解油田开采过程中油层的状况,提高油田开采效率和产量,油田钻井实时在线监测系统…...
经典PID控制算法原理以及优化思路
文章目录0、概念1、理解2、实现3、优化4、引用0、概念 PID算法是工业应用中最广泛算法之一,在闭环系统的控制中,可自动对控制系统进行准确且迅速的校正。PID控制,即Proportional – Integral(I) – Derivative(D) Control, 实际上是三种反馈…...
经典面试题之赋值和深浅拷贝的区别
1.区别 **赋值:**基本数据直接拷贝,互不影响,引用数据把地址赋值给新对象,新旧对象指向同一个地址。 **浅拷贝: **基本类型之间互不影响,对象只会复制对象的第一层基本数据和引用类型的地址,对象内部嵌套的…...
电子取证的电脑配置有关问题,以我仅有的知识为大家建议一下。
电子取证火力很重要,用轻薄本是没法取证的,所以至少是全能本或者是游戏本,牛逼的选手上台式,参考浙警许专家,yyds我专家! 我从实战出发,参考历年“美亚杯”和“长安杯”比赛,给大家…...
【基础算法】单链表的OJ练习(5) # 环形链表 # 环形链表II # 对环形链表II的解法给出证明(面试常问到)
文章目录前言环形链表环形链表 II写在最后前言 本章的OJ练习相对于OJ练习(4)较为简单。不过,本章的OJ最重要的是要我们证明为何可以这么做。这也是面试中常出现的。 对于OJ练习(4):-> 传送门 <-,分割链表以一种类似于归并的思想解得&a…...
MySQL 基础教程[13]
MySQL 基础教程[13]问题1问题1代码问题2问题2代码本系列MySQL 基础教程通过“问题-代码”的方式介绍各类方法,每篇设置2个MySQL综合问题,并给出解决方案。 问题1 kwgl数据库中有学生基本信息表student和系别表dept。表结构及说明如下: student (sid, s…...
个人练习-Leetcode-826. Most Profit Assigning Work
题目链接:https://leetcode.cn/problems/most-profit-assigning-work/ 题目大意:给出一串任务,difficulty表示任务难度,profit表示任务的收益(以下简称diff和pro)。给出一串工人的能力worker。每个工人只能…...
云原生周刊:边缘计算会吞噬云吗?| 2023.3.13
文章推荐 边缘计算吞噬云? 这篇文章讨论了边缘计算对传统云计算的潜在冲击。 边缘计算是一种新型的计算架构,它将计算移动到离数据源和终端设备更近的地方,从而提供更快的响应时间和更好的用户体验。相比之下,云计算是一种集中…...
python+django+vue图书个性化推荐系统
整个系统是由多个功能模块组合而成的,要将所有的功能模块都一一列举出来,然后进行逐个的功能设计,使得每一个模块都有相对应的功能设计,然后进行系统整体的设计。 本图书个性化推荐系统结构图如图python manage.py runserver 开…...
经典文献阅读之--LIO-PPF(增量平面预拟合LIO)
0. 简介 自从ikd-tree出来后,现在越来越多的工作瞄准了增量式这种方法,比如说激光惯导里程计(LIDAR-Inertial Odometry,LIO)的高精度跟踪通常涉及最小化点到平面距离的k最近邻(kNN)搜索&#x…...
ChatGPT背后有哪些关键技术?CSIG企业行带你一探究竟
目录1 ChatGPT的时代2 CSIG企业行3 议题&嘉宾介绍3.1 对生成式人工智能的思考3.2 对话式大型语言模型研究3.3 文档图像处理中的底层视觉技术4 观看入口1 ChatGPT的时代 2015年,马斯克、美国创业孵化器Y Combinator总裁阿尔特曼、全球在线支付平台PayPal联合创始…...
C#基础之面向对象编程(二)
总目录 文章目录总目录前言一、概述1. 定义2. 面向对象的三大特性二、封装1. 定义2. 属性三、继承1. 定义2. 继承的使用3. base 和this四、多态1. 定义2. 重写和重载3. 多态性的实现1、静态多态性2、动态多态性4. 向上转型和向下转型1、定义2、语法格式3、案例结语前言 本文主…...
蓝桥杯刷题冲刺 | 倒计时25天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.完全二叉树1.完全二叉树 题目 链接: 完全二叉树的权值 - 蓝桥云课 (lanqiao.cn) 给…...
c语言—动态内存管理
一.为什么存在动态内存开辟开辟空间的特点:空间开辟大小是固定的数组在申明时,必须指定数组长度,她所需要的内存在编译时分配但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道ÿ…...
请说明Ajax、Fetch、Axios三者的区别
相同点: 1、三者都用于网络请求,但是不同维度 2、 Ajax(Asynchronous Javascript and XML),一种技术的统称,并不是实际的API 3、Fetch是一个具体的API,浏览器里面直接有一个API就叫Fetch 4、 Axios是一个第三方库&…...
阿里p8测试总监,让我们用这份《测试用例规范》,再也没加班过
经常看到无论是刚入职场的新人,还是工作了一段时间的老人,都会对编写测试用例感到困扰?例如: 固然,编写一份好的测试用例需要:充分的需求分析能力 理论及经验加持,作为测试职场摸爬打滚的老人&…...
【Unity】数据持久化路径Application.persistentDataPath
今天突然想到这个路径Application.persistentDataPath,热更的重要路径,该文件夹可读可写,在移动端唯一一个可读写操作的文件夹。移动端可以将本地的资源(资源MD5值配置表)等一些文件放到StreamingAssets文件夹下&#…...
华为OD机试 - 插队(Java JS Python)
题目描述 某银行将客户分为了若干个优先级, 1 级最高, 5 级最低,当你需要在银行办理业务时,优先级高的人随时可以插队到优先级低的人的前面。 现在给出一个人员到来和银行办理业务的时间序列,请你在每次银行办理业务时输出客户的编号。 如果同时有多位优先级相同且最高…...
MongoDB数据库从入门到精通系列之八:调整oplog大小
MongoDB数据库从入门到精通系列之八:调整oplog大小 一、oplog的概念二、oplog大小三、调整oplog大小详细步骤一、oplog的概念 操作日志oplog包含了主节点执行的每一次写操作。oplog是存在于主节点local数据库中的一个固定集合。从节点通过查询此集合以获取需要复制的操作。每个…...
PCL 间接平差法拟合二维直线
目录 一、算法原理二、代码实现三、结果展示四、相关链接一、算法原理 通过传统最小二乘法对点云数据进行二维直线拟合时,可将误差只归因于一个方向上,本文假设误差只存在于 y y y轴方向上,设点云拟合的二维直线方程为: y =...
进程调度的基本过程
这里写目录标题什么是进程进程管理结构体或类的主要属性pid内存指针文件描述符表辅助进程调度的属性并发并行并发什么是进程 进程是操作系统对一个正在运行的程序的一种抽象,也就是说,一个运行起来的程序就是一个进程。 进程又是操作系统进行资源分配的…...
python自动化办公(二)
上接python自动化办公(一) 文章目录文件和目录操作使用shutil库文件查找globfnmatchhashlib文件和目录操作 使用shutil库 shutil库也是Python标准库,它可以处理文件、文件夹、压缩包,能实现文件复制、移动、压缩、解压缩等功能。…...
淄博乐达信息技术网站/ds2600ii色带
int表示中断的含义。 mov ah,4ch int 21h 表示,执行中断指令4c (查下面的表格可知 带返回码结束程序) AH是ax的高位 AH 功能 调用参数 返回参数 00 程序终止(同INT 20H) CS程序段前缀 01 键盘输入并回显 AL输入字符 02 显示输出 DL输出字…...
找外包公司做个网站多少钱/网站建设的推广渠道
在 IntelliJ 使用的时候,我们会经常要对源代码进行查看。 如何在 IntelliJ 中快速进行查看,如何进行比较? 在 IntelliJ 中,你可以使用快捷键进行查看,你也可以通过鼠标进行查看。 我们常用的查看功能使用的是查看一个…...
太原便宜做网站的公司/网店推广平台有哪些
思科(Cisco)VLAN在配置 思路: 一.配置好DHCP、DNS、web服务器(在这文章的第三) 二.先配置两个交换机的vlan 三.配置路由器 四.检查设备的互通情况 每一步操作都有详细解析哦 拓扑图结构 1.VLAN的理解 交换机可以划分…...
政府网站建设专题的目的/免费发外链
上一期我对BBR进行修改的目标很简单,就是提高算法的RTT公平性,主要修改点有3个: 固定增益系数改为了RTT的减函数。RTT相关的steady phase改为了固定时间。探测到带宽腾出时,马上进行up probe。 详情参见: https://zh…...
应届生招聘去哪个网站/北京官网seo
文章目录1.处理客户端删除状态请求1.1 InstanceResource.deleteStatusUpdate()1.2 PeerAwareInstanceRegistryImpl.deleteStatusOverride()1.3 AbstractInstanceRegistry.deleteStatusOverride()1.4 PeerAwareInstanceRegistryImpl.replicateToPeers()1.处理客户端删除状态请求…...
如何做视频网站流程图/国外免费推广平台有哪些
1 volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别。理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个监视器锁对这些单个读/写操作做了同步。下面我们通过具体的示例来说明&…...