六、python Django REST framework[认证、权限、限流]_python 权限认证_黑日里不灭的light的博客-程序员秘密

技术标签: python  # Python Django学习  django  后端  

django 3.2.13

一、认证

解释:认证有五大认证类: BasicAuthenticationSessionAuthenticationTokenAuthenticationRemoteUserAuthentication,他们都继承了BaseAuthentication

认证流程代码:

1. 先通过分发进入认证环节  def dispatch(self, request, *args, **kwargs):[rest_framework.views.py大约485行前后]
2. 先通过request = self.initialize_request(request, *args, **kwargs)来获得一个新的request,里面已经读取过了配置信息,知道下面要用什么认证方式
3. 该函数里面self.initial(request, *args, **kwargs)进入认证、权限、限流功能
4. initial里面的self.perform_authentication(request)进行认证
5. perform_authentication实际调用user()[rest_framework.requests.py大约220行前后]
6. 由user里面的_authenticate进入到user_auth_tuple = authenticator.authenticate(self)这里开始的authenticate[rest_framework.authentication.py]开始根据配置选择认证方式

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

  • 全局配置
    • 写入setting.py文件
REST_FRAMEWORK = {
    
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',  # Basic认证
        'rest_framework.authentication.SessionAuthentication',  # session认证
        'rest_framework.authentication.TokenAuthentication',  # session认证
        'rest_framework.authentication.RemoteUserAuthentication',  # session认证
    )
}
  • 局部配置
    • 写入views.py
from rest_framework.authentication import SessionAuthentication, BasicAuthentication

class TestGenericAPIView(ModelViewSet):
    authentication_classes = (SessionAuthentication, BasicAuthentication) # 写在这里
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

1.基础认证

1.1 BasicAuthentication

认证方式原理:这种方式不需要Cookie和Session,只需要客户端发起请求的时候,在头部Header中提交用户名和密码(base64格式加密)。如果没有附加,会弹出一个对话框,要求输入用户名和密码。但是它不提供信息加密措施,通常都是以base64编码传输。

好处:简单,不需要Cookie和Session,被广泛支持,一般用于内网比如路由器验证之类

缺点:不安全不能保存信息,关闭浏览器即失效,不能自己退出,比较落后,信息很容易被篡改,目前并不是特别推荐使用

源码简单分析:

# 承接上面最初的第5步,开始根据配置选择认证方式
1. 认证方式[rest_framework.authentication.py]的BasicAuthentication的authenticate()函数
2. 在authenticate()里面调用auth = get_authorization_header(request).split()
3. get_authorization_header()开始去获取header传来关于名称和密码的md5数据
4. 在下面return self.authenticate_credentials(userid, password, request)[大约87]调用self.authenticate_credentials()
5. 其中这个函数里面的authenticate()[大约98]开始查询数据库验证密码

1.2 SessionAuthentication

session和cookie:cookie是储存在用户端即浏览器里面,session储存在服务器里面,cookie因为在用户端所以安全差,而且储存内容少,所以把关键内容写入到服务器专门创建的session表里面。当用户第一次请求,服务器就会在session表单里面写入(多个浏览器一个用户,算多次请求,过期或者退出,session可能会消失[依据不同处理逻辑来定]),之后每次请求都会验证是否第一次请求,如果不是则服务器会确定用户操作

认证方式原理:比如用户登录之类都是用其来实现,其是通过验证用户登录后服务器发送给session表单新创建的id号写入cookie(里面有字段为),请求时携带着cookie,提取到服务器去获取cookie里面session的id然后去找到服务器里面的session表去获取里面储存的信息,获取用户身份信息进行验证。Django默认是这种方式

优点:cookie能长期保存能退出,自主加密比较安全

缺点:cookie不能跨域,服务器数据库保存cookie数据,用户多,服务器储存session压力压力大

源码简单分析:

# 承接上面最初的第5步,开始根据配置选择认证方式
1. 通过user = getattr(request._request, 'user', None)获取request._request属性
2. user属性相当于去获取requests.user这个方法相当于去读取cookie解密session并且去数据库里面提取出,当前的用户。

1.3 TokenAuthentication

介绍:未来再介绍

1.4 RemoteUserAuthentication

介绍:未来再介绍

二、权限

基础认证类:

  • AllowAny 允许所有用户
  • IsAuthenticated 仅通过认证的用户
  • IsAdminUser 仅管理员用户
  • IsAuthenticatedOrReadOnly 认证的用户可以完全操作,否则只能get读取

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

  • 全局配置
    • 写入setting.py文件
REST_FRAMEWORK = {
    
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}
  • 局部配置
    • 写入views.py
from rest_framework.authentication import SessionAuthentication, BasicAuthentication

class TestGenericAPIView(ModelViewSet):
    authentication_classes = (SessionAuthentication, ) # 认证方法选择
    permission_classes = (IsAuthenticated,) # 关键在这
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

自定义权限
导入:from rest_framework.permissions import BasePermission
解释:需要继承BasePermission,并重写has_permission'或者Falsehas_object_permission两个方法即可

区别:has_permission 是用户可以对这个视图有没有 GET POST等权限进行区分,has_object_permission 是 has_permission返回True后,再判断这个用户有没有对一个具体的对象有没有操作权限

class IsOwnerOrReadOnly(BasePermission):
    def has_permission(self, request, view):
        if request.method =="DELETE":
            return True
        elif request.method =="GET":
            return True
        else:
            return False

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

注意:关于has_object_permission()没有执行,通过翻看源码。①通过继承ModelViewSet类(里面又继承CreateModelMixin、UpdateModelMixin等等这些类,不知道看上篇文章),UpdateModelMixinRetrieveModelMixinDestroyModelMixin这三个类(做数据库变动操作和单一查询操作),其会在每次执行前调用self.get_object()该方法用来检查其是否存在,以及是否有操作权限(这就是关键),其在里面调用 self.check_object_permissions(self.request, obj)check_object_permissions又调用自己写的has_object_permission;②自己写修改、删除、单一查询要调用self.get_object()该方法,下面展示一段UpdateModelMixin的源代码方便学习self.get_object怎么用

class RetrieveModelMixin:
    """
    Retrieve a model instance.
    """
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

三、限流

基础限制类:

  • AnonRateThrottle 限制未登录用户

  • UserRateThrottle 限制登录用户

  • ScopedRateThrottle 具体视图限制

使用方法:

解释:如果配置全局就无需专门写入局部配置,同理配置局部无需专门写入全局,理由(django在APIView父类里面默认会读取全局配置的,如果局部写相当于覆盖全局配置)

  • 限制登录与未登录

导入:from rest_framework.throttling import UserRateThrottle

# 当使用登录与未登录限制的时候,所有视图的访问都会被记录在内
REST_FRAMEWORK = {
    
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
    
        'anon': '100/day', # 未登录用户一天访问最多100次,anon是默认的
        'user': '1000/day'# 登录用户一天访问最多1000次
    } # 可以使用 second, minute, hour 或day来指明周期
}
class TestGenericAPIView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    throttle_classes = (UserRateThrottle,) # 关键
  • 限制具体视图
REST_FRAMEWORK = {
    
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle', # 让其靠上先生效
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
    
        'anon': '100/day', # 未登录用户一天访问最多100次,anon是默认的
        'user': '10/hour', # 登录用户一天访问最多1000次
        'do':'3/hour' # 关键
    },

}
class TestGenericAPIView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    throttle_classes = (UserRateThrottle,) # 不加默认也有主要靠setting.py里面
    throttle_scope = 'do' # 单独视图限流关键
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46765649/article/details/126237710

智能推荐

收藏 |《动手学深度学习》中文版PDF_小白学视觉的博客-程序员秘密

对于初学者来说,直接阅读英文资料,效率慢,估计读着读着都没有信心读下去了。对于初学者,中文资料是再好不过了。今天小编就来安利一本中文资料——中文版本的《动手学深度学习》。资料领取:扫码后台...

让GIS三维可视化变得简单-Cesium地球初始化_isboyjc的博客-程序员秘密

前言开发中我们通常会需要一个干净的三维地球实例,本文将介绍 Cesium 如何初始化一个地球,包括地图控件的显示隐藏以及一些常用影像和标注的加载预览Demo[1]Cesium 是一款面向...

机器学习——常用的回归模型性能评价指标_從疑開始的博客-程序员秘密

对于回归而言,更注重的是模型拟合的曲线,相对于真实曲线的误差。主要包括:拟合优度/R-Squared,校正决定系数(Adjusted R-square),均方误差(MSE),均方根误差(RMSE),误差平方和(SSE),平均绝对误差(MAE),平均绝对百分比误差(MAPE)。1、均方误差(MSE)均方误差是指:观测值与真值偏差的平方和与观测次数的比值公式:MSE相当于模型中的损失函数,线性回归过程中尽量让该损失函数最小。那么模型之间的对比也可以用它来比较。MSE可以评价模型的预测精度,MSE的值越

C++中typedef与const、指针_棉猴的博客-程序员秘密

1 typedef的用法在C++中,typedef关键字用来定义类型的别名。typedef double wages;此时,wages是double的别名,可以将wages作为数据类型来定义其他变量。wages mywage;其中,mywage的类型是double。2 使用typedef定义指针的别名使用typedef定义指针的别名的方法与“1 typedef的用...

Java 8中处理日期和时间示例_java编写一个处理日期的方法_weixin_41488437的博客-程序员秘密

在Java 8以前,日期和时间处理一直被广大java程序员抱怨太难用,首先是java.util和java.sql中,都包含Date类,如果要进行时间格式化,还需要java.text.DateFormat类处理。同时java.util.Date中既包含了日期,又包含了时间,所以java8新的日期和时间库,很好的解决了以前日期和时间类的很多弊端。并且也借鉴了第三方日期库joda很多的优点。在jav...

{Unity} WebGL版本不能使用反射机制以及解决方法_unity动画没有反射_n5的博客-程序员秘密

我们的项目导出WebGL后运行不了,因为我们使用了System.Reflection.Assembly.GetExecutingAssembly().CreateInstance 来根据类名创建对象。解决方法是创建一个工厂类,根据类名调用不同的代码new对象。而然这样很麻烦,并且每次都需要修改这个工厂。我想了一个方法就是使用一个编辑器脚本自动生成工厂类,思路是利用反射机制获取一个assembly内

随便推点

iOS - Socket-长连接(心跳包)的实现_ios socket 发送心跳_xtayqria的博客-程序员秘密

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

运行时识别类型信息_运行时信息_buaa-Hj的博客-程序员秘密

      获取类型信息的必要性:运行时类型信息可以使程序员只能从编译期执行面向对象操作的禁锢中释放出来,使得可以在运行时发现和使用类型信息。主要两种方式:1、RTTI     2、反射机制      多态是面向对象编程的一个重要思想,我们面向接口(或者可以是基类)编程,然后基类中的方法会动态绑定到衍生类,这样只需要面对接口编程,便可以产生运行时的多态,大大简化了程序员的工作量。但是如果我们需要对...

keras的图像预处理全攻略(五)—— ImageDataGenerator 类结合神经网络的实践_keras.utils.np_utils.to_categorical(y_train, n_cla_LoveMIss-Y的博客-程序员秘密

前言:前面的系列文章已经系统的说明了keras的图像预处理操作,有原理部分、也有少量实践部分,可以参考下面的文章:keras的图像预处理全攻略(四)—— ImageDataGenerator 类实践案例keras的图像预处理全攻略(三)—— ImageDataGenerator 类的辅助类keras的图像预处理全攻略(二)—— ImageDataGenerator 类ker...

数据结构 一元多项式的创建、显示、相加、相减、相乘_Belieber_ly的博客-程序员秘密

#include"Polyn.h"void main(){ Polynomial pa,pb,pc; InitPolyn(pa); InitPolyn(pb); InitPolyn(pc); int m; int select = 1; while(select) { printf("*****************************************

缓存原理过程和几种缓存方案_敲起来blingbling的博客-程序员秘密

缓存1 简介前端缓存主要是分为HTTP缓存(强缓存、协商缓存)和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器上设置;而浏览器缓存主要在前端js进行设置。缓存是性能优化中简单高效的一种方式。它可以缩短请求资源的距离,减少延迟,降低网络负荷。浏览器在向服务器请求资源之前,先查询一下缓存中是否存在需要的资源,如果存在,那优先从缓存中读取。当缓存不存在或过期,再向服务器发送请求。2 缓存过程浏览器第一次向服务器发起请求,会根据返回的响应报文中的缓存标识,决定是否缓存结果,

Bzoj3456 城市规划_weixin_34405354的博客-程序员秘密

Time Limit: 40 SecMemory Limit: 256 MBSubmit: 681Solved: 383Description刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或间接的连通.为了省钱, 每两个城市之间最多只能有一...

推荐文章

热门文章

相关标签