二十二、身份验证与权限
一、 准备工作
为了讲清楚身份验证与权限,我们再创建一个应用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.PermissionDeniedorexceptions.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、案例结语前言 本文主…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...

