一、概述

认证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制。然后 权限 和 限制 组件决定是否拒绝这个请求。

简单来说就是:

认证确定了你是谁

权限确定你能不能访问某个接口

限制确定你访问某个接口的频率

二、认证

REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案。

三、自定义Token认证

model 定义一个包含token字段的用户表

  1. class UserInfo(models.Model):
  2. name = models.CharField(max_length=32)
  3. pwd = models.CharField(max_length=32)
  4. vip = models.BooleanField(default=False)
  5. token = models.CharField(max_length=128, null=True, blank=True)

定义登录视图:

  1. class LoginView(APIView):
  2. def post(self, request):
  3. name = request.data.get('name')
  4. pwd = request.data.get('pwd')
  5. if name and pwd:
  6. user_obj = models.UserInfo.objects.filter(name=name, pwd=pwd).first()
  7. if user_obj:
  8. # 登陆成功
  9. # 生成token(时间戳 + Mac地址)
  10. token = uuid.uuid1().hex
  11. # 1.保存在用户表中
  12. user_obj.token = token
  13. user_obj.save()
  14. # 2.给用户返回
  15. return Response({'error_no': 0, 'token': token})
  16.  
  17. else:
  18. # 用户名或密码错误
  19. return Response({'error_no': 1, 'error': '用户名或密码错误'})
  20. else:
  21. return Response('无效的参数')

创建auth.py自定义一个认证类

  1. from rest_framework.authentication import BaseAuthentication
  2. from auth_demo import models
  3. from rest_framework.exceptions import AuthenticationFailed
  4.  
  5. class MyAuth(BaseAuthentication):
  6. '''自定义认证类'''
  7.  
  8. def authenticate(self, request):
  9. token = request.query_params.get ('token')
  10. if token:
  11. # 如果请求url中携带有token参数
  12. user_obj = models.UserInfo.objects.filter(token=token).first()
  13. if user_obj:
  14. # token 是有效的,返回一个元组
  15. return user_obj, token # request.user, request.auth
  16. else:
  17. raise AuthenticationFailed('无效的token')
  18. else:
  19. raise AuthenticationFailed('请求的URL中必须携带token参数')

局部配置认证

在views中自定义一个测试类TestAuthView

  1. from auth_demo.auth import MyAuth
  2. from auth_demo.permissions import MyPermission
  3. # 登录之后才能看到数据接口
  4. class TestAuthView(APIView):
  5. authentication_classes = [MyAuth, ] # 局部配置认证
  6.  
  7. def get(self, request):
  8. print(request.user.name)
  9. print(request.auth)
  10. return Response('这个视图里面的数据只有登录后才能看到!')

全局配置认证

  1. # 在settings.py中配置
  2. REST_FRAMEWORK = {
  3. "DEFAULT_AUTHENTICATION_CLASSES": ["auth_demo.auth.MyAuth", ]
  4. }

四、权限

自己动手写一个权限组件

  1. from rest_framework.permissions import BasePermission
  2.  
  3. class Mypermission(BasePermission):
  4. message = '只有VIP才能访问'
  5.  
  6. def has_permission(self, request, view):
  7. # vip才有访问权限
  8. # request.user:当前经过认证的用户对象
  9. # 如果没有认证 request.user就是匿名用户
  10. if not request.auth:
  11. # 认证没有通过
  12. return False
  13. if request.user.vip:
  14. return True
  15. else:
  16. return False

视图级别配置

  1. from auth_demo.auth import MyAuth
  2. from auth_demo.permissions import Mypermission
  3. # 登录之后才能看到数据接口
  4. class TestAuthView(APIView):
  5. authentication_classes = [MyAuth, ] # 局部配置认证
  6. permission_classes = [Mypermission, ] # 试图级别配置权限
  7.  
  8. def get(self, request):
  9. print(request.user.name)
  10. print(request.auth)
  11. return Response('这个视图里面的数据只有登录后才能看到!')

全局级别设置

只需要在settings的DRF配置项中添加权限类

  1. # DRF的配置
  2. REST_FRAMEWORK = {
  3. # 配置默认使用的版本控制类
  4. 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
  5. # 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning',# url参数控制版本
  6. 'DEFAULT_VERSION': 'v1', # 默认的版本
  7. 'ALLOWED_VERSIONS': ['v1', 'v2'], # 有效的版本
  8. 'VERSION_PARAM': 'version', # 版本的参数名与URL conf中一致
  9. # 自定义认证
  10. 'DEFAULT_AUTHENTICATION_CLASSES': ['auth_demo.auth.MyAuth', ],
  11. # 自定义权限
  12. 'DEFAULT_PERMISSION_CLASSES': ['auth_demo.permissions.MyPermission', ]
  13. }

五、限制

DRF内置了基本的限制类,首先自己动手写一个限制类,熟悉限制组件的执行过程。

自定义限制10秒内只能访问3次

自定义的限制类必须实现2个方法

  1. allow_request() wait()
    分析:
  1. # history = ['9:56:12', '9:56:10', '9:56:09', '9:56:08'] # '9:56:18' - '9:56:12'
  2.  
  3. # history = ['9:56:19', '9:56:18', '9:56:17', '9:56:08']
  4.  
  5. # 最后一项到期的时间就是下一次允许请求的时间
  6.  
  7. # 最后一项到期的时间:history[-1] + 10
  8.  
  9. # 最后一项还剩多少时间过期
  10. # history[-1] + 10 - now

实现:

  1. import time
  2.  
  3. # 存放访问记录信息
  4. visit_record= {}
  5. class MyThrottle(object):
  6. def __init__(self):
  7. self.history = None
  8.  
  9. def allow_request(self, request, view):
  10. # 拿到当前请求的ip作为访问记录的key
  11. ip = request.META.get('REMOTE_ADDR')
  12. # 拿到当前请求的时间戳
  13. now = time.time()
  14. if ip not in visit_record:
  15. visit_record[ip] = []
  16. # 把当前请求的访问记录拿出来保存到一个变量中
  17. history = visit_record[ip]
  18. self.history = history
  19. # 循环访问历史,把超过10秒中的请求时间去掉
  20. while history and now - history[-1] > 10:
  21. history.pop()
  22. # 此时 history中只保存了最近10秒中的访问记录
  23. if len(history) >= 3:
  24. # 限制十秒钟内最多只能访问三次
  25. return False
  26. else:
  27. # 将当前访问时间插入history的首位
  28. self.history.insert(0, now)
  29. return True
  30.  
  31. def wait(self):
  32. '''告诉客户还需等待多久'''
  33. now = time.time()
  34. return self.history[-1] + 10 - now

单个视图类使用

  1. from auth_demo.auth import MyAuth
  2. from auth_demo.permissions import MyPermission
  3. from auth_demo.throttle import MyThrottle
  4. # 登录之后才能看到数据接口
  5. class TestAuthView(APIView):
  6. authentication_classes = [MyAuth, ] # 局部配置认证
  7. permission_classes = [MyPermission, ] # 视图级别配置权限
  8. throttle_classes = [MyThrottle, ] # 限制单个视图访问频率
  9.  
  10. def get(self, request):
  11. print(request.user.name)
  12. print(request.auth)
  13. return Response('这个视图里面的数据只有登录后才能看到!')

全局使用

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_AUTHENTICATION_CLASSES': ['auth_demo.auth.MyAuth', ],
  3. 'DEFAULT_PERMISSION_CLASSES': ['auth_demo.permissions.MyPermission', ]
        
  4. "DEFAULT_THROTTLE_CLASSES": ["auth_demo.throttle.MyThrottle", ]
  5. }

使用内置限制类

  1. from rest_framework.throttling import SimpleRateThrottle
  2.  
  3. class VisitThrottle(SimpleRateThrottle):
  4.  
  5. scope = "xxx"
  6.  
  7. def get_cache_key(self, request, view):
  8. return self.get_ident(request)

全局配置

  1. settingsREST_FRAMEWORK配置中加一个:
  1. REST_FRAMEWORK = {
  2. # 限制类
  3. "DEFAULT_THROTTLE_CLASSES": ["auth_demo.throttle.VisitThrottle", ],
  4. "DEFAULT_THROTTLE_RATES": {
  5. "xxx": "1/s",
  6. },
  7. }

DRF的认证、权限 和 限制的更多相关文章

  1. DRF(4) - 认证、权限组件

    一.引入 通过前面三节课的学习,我们已经详细了解了DRF提供的几个重要的工具,DRF充分利用了面向对象编程的思想,对Django的View类进行了继承,并封装了其as_view方法和dispatch方 ...

  2. DRF的认证,频率,权限

    1,DRF的认证 初识认证:浏览器是无状态的,一次导致每次发的请求都是新的请求,所以每次请求,服务器都会进行校验,这样就很繁琐,这趟我们就需要给每一个用户登录后一个新的标识,浏览器每次都会带着这个唯一 ...

  3. 实战-DRF快速写接口(认证权限频率)

    实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestframework3.13 测试工具 Postma ...

  4. DRF 版本 认证

    DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢大家都知道我们开发项目是有多个版本的 当我们项目越来越更新~版本就越来越多我们不可能新的版本出了~以前旧的版本 ...

  5. 9) drf JWT 认证 签发与校验token 多方式登陆 自定义认证规则反爬 admin密文显示

    一 .认证方法比较 1.认证规则图 django 前后端不分离 csrf认证 drf 前后端分离 禁用csrf 2. 认证规则演变图 数据库session认证:低效 缓存认证:高效 jwt认证:高效 ...

  6. DRF内置权限组件之自定义权限管理类

    DRF内置权限组件permissions 权限控制可以限制用户对于视图的访问和对于具体数据对象的访问. 在执行视图的dispatch()方法前,会先进行视图访问权限的判断 在通过get_object( ...

  7. DRF 三大认证的配置及使用方法

    目录 三大认证 一.身份认证 1.身份认证配置 1.1 全局配置身份认证模块 1.2 局部配置身份认证模块 2.drf提供的身份认证类(了解) 3.rf-jwt提供的身份认证类(常用) 4.自定义身份 ...

  8. DRF JWT认证(二)

    快速上手JWT签发token和认证,有这一篇就够了,DRF自带的和自定义的都帮你总结好了,拿去用~

  9. 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限

    开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他 ...

  10. Kafka认证权限配置(动态添加用户)

    之前写过一篇Kafka ACL使用实战,里面演示了如何配置SASL PLAINTEXT + ACL来为Kafka集群提供认证/权限安全保障,但有一个问题经常被问到:这种方案下是否支持动态增加/移除认证 ...

随机推荐

  1. Deep Learning 学习笔记(6):神经网络( Neural Network )

    神经元: 在神经网络的模型中,神经元可以表示如下 神经元的左边是其输入,包括变量x1.x2.x3与常数项1, 右边是神经元的输出 神经元的输出函数被称为激活函数(activation function ...

  2. 第一章 Spring整体架构和环境搭建(待续)

    ········

  3. 仿照admin写一个startk组件

    settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.conten ...

  4. linux rz -e

    linux shell rz和sz是终端下常用的文件传输命令,rz和sz通过shell被调用,其中rz用于从启用终端的系统上传文件到目标系统(终端登录的目标系统), 这里不过多介绍这些命令,只是记录一 ...

  5. SecureCRT中某些命令提示符下按Backspace显示^H的解决方法

    SecureCRT中某些命令提示符下按Backspace显示^H的解决方法 安装了Apache Derby数据库服务器之后,使用ij客户端去连接derby服务端,可是在ij中输入命令的时候,每当输入错 ...

  6. mysql存储引擎简介

  7. Spring框架找不到 applicationContext.xml文件,可能是由于applicationContext.xml文件的路径没有放在根目录下造成的

    Spring框架找不到 applicationContext.xml文件,可能是由于applicationContext.xml文件的路径没有放在根目录下造成的

  8. mybatis 框架 的应用之三(操作两张没有关联的表,存在主键和外键关系)

    #注意:要配置开启多条语句操作,否则会报错( org.apache.ibatis.exceptions.PersistenceException) lf-driver=com.mysql.jdbc.D ...

  9. 面试题:servlet jsp cook session 背1

    一.Servlet是什么?JSP是什么?它们的联系与区别是什么? Servlet是Java编写的运行在Servlet容器的服务端程序,狭义的Servlet是指Servlet接口,广义的Servlet是 ...

  10. https抓包