一. 认证

  (你是谁?)

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


自定义Token认证

  第一步 : 建表>>>>

    定义一个用户表和一个保存用户Token的表

  1. class UserInfo(models.Model):
  2. username = models.CharField(max_length=16)
  3. password = models.CharField(max_length=32)
  4. type = models.SmallIntegerField(
  5. choices=((0, '普通用户'), (1, 'VIP用户')),
  6. default=0
  7. )
  8.  
  9. class Token(models.Model):
  10. user = models.OneToOneField(to='UserInfo')
  11. token_code = models.CharField(max_length=128)

  第二步: 定义一个登陆视图 >>>>

  1. from rest_framework.views import APIView
  2. from app2 import models
  3. from rest_framework.response import Response
  4. import hashlib, time
  5.  
  6. def get_random_token(username):
  7. """
  8. 根据用户名和时间戳生成随机token
  9. """
  10. timestamp = str(time.time())
  11. m = hashlib.md5(bytes(username, encoding="utf-8"))
  12. m.update(bytes(timestamp, encoding="utf-8"))
  13. return m.hexdigest()
  14.  
  15. class LoginView(APIView):
  16. """
  17. 校验用户名是否正确从而生成token的视图
  18. """
  19. def post(self, request):
  20. res = {"code": 0}
  21. # print(request.data)
  22. username = request.data.get("username")
  23. password = request.data.get("password")
  24.  
  25. user = models.UserInfo.objects.filter(username=username, password=password).first()
  26. if user:
  27. token = get_random_token(username)
  28. models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
  29. res["token"] = token
  30. else:
  31. res["code"] = 1
  32. res["error"] = "用户名或密码错误"
  33. return Response(res)

  第三步: 定义一个认证类 >>>>

  1. from rest_framework.authentication import BaseAuthentication
  2. from rest_framework.exceptions import AuthenticationFailed
  3. from app2 import models
  4.  
  5. class MyAuth(BaseAuthentication):
  6. def authenticate(self, request):
  7. # if request.method in ["POST", "PUT", "DELETE"]:
  8.  
  9. # 如果在表单中需要判断请求方式 由于表单是post请求,所以获取token 的方式为 request.data.get("token")
  10. # request.query_params为url中的参数
  11. request_token = request.query_params.get("token", None)
  12. if not request_token:
  13. raise AuthenticationFailed('q.缺少token')
  14.  
  15. token_obj = models.Token.objects.filter(token_code=request_token).first()
  16. if not token_obj:
  17. raise AuthenticationFailed("无效的Token")
  18. # token_obj.user 通过token这张表的对象和user这个关联字段 找到 UserInfo表的对象及当前用户对象
  19. return token_obj.user, request_token
  20.  
  21. # else:
  22. # return None, None

  第四步: 使用认证类 >>>>

    视图级别认证

  1. class CommentViewSet(ModelViewSet):
  2.  
  3. queryset = models.Comment.objects.all()
  4. serializer_class = app01_serializers.CommentSerializer
  5. authentication_classes = [MyAuth, ]

    全局级别认证

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

二. 权限

  (你能干什么?) 设置只有VIP才能看到的东西

第一步: 自定义一个权限类

  1. """
  2. 自己动手写一个权限组件
  3. """
  4. from rest_framework.permissions import BasePermission
  5.  
  6. class MyPermission(BasePermission):
  7.  
  8. message = '只有VIP才能访问'
  9.  
  10. def has_permission(self, request, view):
  11. # 认证类中返回了token_obj.user, request_token
  12. # request.auth 等价于request_token
  13. if not request.auth:
  14. return False
  15. # request.user为当前用户对象
  16. if request.user and request.user.type == 1: # 如果是VIP用户
  17. print("requ", request.user, type(request.user))
  18. return True
  19. else:
  20. return False

第二步: 使用

  视图级别配置

  1. class CommentViewSet(ModelViewSet):
  2.  
  3. queryset = models.Comment.objects.all()
  4. serializer_class = app01_serializers.CommentSerializer
  5. authentication_classes = [MyAuth, ]
  6. permission_classes = [MyPermission, ]

  全局级别设置

  1. # 在settings.py中设置rest framework相关配置项
  2. REST_FRAMEWORK = {
  3. "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
  4. "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
  5. }

三. 控制

  (你一分钟能干多少次?)**好像有点污~~

第一步: 自定义限制类 >>>>

  1. import time
  2.  
  3. # from rest_framework.throttling import
  4. visit_record = {}
  5.  
  6. class MyThrottle(object):
  7.  
  8. def __init__(self):
  9. self.history = None
  10.  
  11. def allow_request(self, request, view):
  12. # 拿到当前的请求的ip作为访问记录的 key
  13. ip = request.META.get('REMOTE_ADDR')
  14. # 拿到当前请求的时间戳
  15. now = time.time()
  16. if ip not in visit_record:
  17. visit_record[ip] = []
  18. # 把当前请求的访问记录拿出来保存到一个变量中
  19. history = visit_record[ip]
  20. self.history = history
  21. # 循环访问历史,把超过10秒钟的请求时间去掉
  22. while history and now - history[-1] > 10:
  23. history.pop()
  24. # 此时 history中只保存了最近10秒钟的访问记录
  25. if len(history) >= 3:
  26. return False
  27. else:
  28. # 判断之前有没有访问记录(第一次来)
  29. self.history.insert(0, now)
  30. return True
  31.  
  32. def wait(self):
  33. """告诉客户端还需等待多久"""
  34. now = time.time()
  35. return self.history[-1] + 10 - now
  36.  
  37. # history = ['9:56:12', '9:56:10', '9:56:09', '9:56:08'] # '9:56:18' - '9:56:12'
  38.  
  39. # history = ['9:56:19', '9:56:18', '9:56:17', '9:56:08']
  40.  
  41. # 最后一项到期的时间就是下一次允许请求的时间
  42.  
  43. # 最后一项到期的时间:now - history[-1] > 10
  44.  
  45. # 最后一项还剩多少时间过期
  46. # history[-1] + 10 - now

第二步: 使用 >>>

  视图中使用

  1. class CommentViewSet(ModelViewSet):
  2.  
  3. queryset = models.Comment.objects.all()
  4. serializer_class = app01_serializers.CommentSerializer
  5. throttle_classes = [MyThrottle, ]

  全局中使用

  1. # 在settings.py中设置rest framework相关配置项
  2. REST_FRAMEWORK = {
  3. "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
  4. "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
  5. "DEFAULT_THROTTLE_CLASSES": ["app01.utils.MyThrottle", ]
  6. }

其实还可以使用内置限制类

  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. # 在settings.py中设置rest framework相关配置项
  2. REST_FRAMEWORK = {
  3. "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
  4. # "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
  5. "DEFAULT_THROTTLE_CLASSES": ["app01.utils.VisitThrottle", ],
  6. "DEFAULT_THROTTLE_RATES": {
  7. "xxx": "5/m",
  8. }
  9. }

看源码:

  1.认证流程

  2. 权限

Django REST Framework 认证 - 权限 - 限制的更多相关文章

  1. Django REST framework认证权限和限制和频率

    认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...

  2. Django REST framework认证权限和限制 源码分析

    1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...

  3. Django Rest Framework(认证、权限、限制访问频率)

    阅读原文Django Rest Framework(认证.权限.限制访问频率) django_rest_framework doc django_redis cache doc

  4. Django Rest framework 之 权限

    django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) django res ...

  5. 04 Django REST Framework 认证、权限和限制

    目前,我们的API对谁可以编辑或删除代码段没有任何限制.我们希望有更高级的行为,以确保: 代码片段始终与创建者相关联. 只有通过身份验证的用户可以创建片段. 只有代码片段的创建者可以更新或删除它. 未 ...

  6. django 之(三) --- 认证|权限

    用户模块 登陆注册1:Django2.0  [ 1:N ] user/url.py from django.urls import path from user.views0 import UserT ...

  7. rest framework 认证 权限 频率

    认证组件 发生位置 APIview 类种的 dispatch 方法执行到 initial 方法 进行 认证组件认证 源码位置 rest_framework.authentication  源码内部需要 ...

  8. Django Rest Framework之权限

    基本代码结构 url.py: from django.conf.urls import url, include from app import views urlpatterns = [ url(r ...

  9. Django REST framework - 认证

    目录 认证 DRF 5种验证方式 如何确定身份验证? 设置身份验证方案 案例: 基于自定义Token认证 第一步: 定义一个用户表和一个保存用户Token的表 第二步: 定义一个登陆视图 第三步定义一 ...

随机推荐

  1. linux 遇到(vsftpd)—500 OOPS:chroot

    今天在用vsftpd 时出现一个问题: 500 OOPS:chroot 解决办法: 1.关闭SELINUX [root@localhost ~]#vi /etc/sysconfig/selinux # ...

  2. 提高生产力:Web开发基础平台WebCommon的设计和实现

    Web开发中,存在着各种各样的重复性的工作.为了提高开发效率,不在当码农,我在思考和实践如何搭建一个Web开发的基础平台. Web开发基础平台的目标和功能 1.提供一套基础的开发环境,整合了常用的框架 ...

  3. 导出MNIST的数据集

    在TensorFlow的官方入门课程中,多次用到mnist数据集. mnist数据集是一个数字手写体图片库,但它的存储格式并非常见的图片格式,所有的图片都集中保存在四个扩展名为idx3-ubyte的二 ...

  4. 用户登录记住用户名导致表单自动填充bug解决方法

    最近做项目出现了一个极其讨厌的bug:在用户登录网站时,浏览器会自动提示是否记住密码,当选择记住密码时,正常浏览网页,会发现有那么几个input输入框会自动填充用户名,非常讨厌, 于是就觉得挺简单的一 ...

  5. CentOS中防火墙相关的命令(CentOS7中演示)

    CentOS中防火墙程序主要是firewall和iptables,CentOS7中firewall服务已经默认安装好了,而iptables服务需要自己用yum  install  iptabes-se ...

  6. mysql查询优化--临时表和文件排序(Using temporary; Using filesort问题解决)

    先看一段sql: <span style="font-size:18px;">SELECT * FROM rank_user AS rankUser LEFT JOIN ...

  7. PL/SQL控制语句

    本节要点: l  选择结构控制语句 if条件控制语句 Case语句 l  循环结构控制语句 基本loop循环 for循环 while循环 嵌套循环 PL/SQL既然是面向过程的编程语言,那么它就有针对 ...

  8. easy-ui采坑事件

    新用户首次登陆修改密码 imput标签中使用easyui自带的class="easyui-passwordbox"可以是密码隐藏变成黑点但是无法禁用输入法,然后果断的加了一个typ ...

  9. 简单易学的机器学习算法——神经网络之BP神经网络

    一.BP神经网络的概念     BP神经网络是一种多层的前馈神经网络,其基本的特点是:信号是前向传播的,而误差是反向传播的.详细来说.对于例如以下的仅仅含一个隐层的神经网络模型: watermark/ ...

  10. 经验之谈—OAuth授权流程图

    事实上我们在开发中,常常须要解决获得用户的一些特定的数据,比方:能够选择使用微博登陆.使用QQ登陆等等.然后我们间接的获得用户的头像.昵称等信息.这些都涉及到OAuth授权的内容 OAuth授权有这么 ...