认证、权限和限制

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

简单来说就是:

认证确定了你是谁

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

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

认证

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

接下类我们就自己动手实现一个基于Token的认证方案:

自定义Token认证

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

class UserInfo(models.Model):
username = models.CharField(max_length=16)
password = models.CharField(max_length=32)
type = models.SmallIntegerField(
choices=((1, '普通用户'), (2, 'VIP用户')),
default=1
) class Token(models.Model):
user = models.OneToOneField(to='UserInfo')
token_code = models.CharField(max_length=128)

定义一个登录视图:

def get_random_token(username):
"""
根据用户名和时间戳生成随机token
:param username:
:return:
"""
import hashlib, time
timestamp = str(time.time())
m = hashlib.md5(bytes(username, encoding="utf8"))
m.update(bytes(timestamp, encoding="utf8"))
return m.hexdigest() class LoginView(APIView):
"""
校验用户名密码是否正确从而生成token的视图
"""
def post(self, request):
res = {"code": 0}
print(request.data)
username = request.data.get("username")
password = request.data.get("password") user = models.UserInfo.objects.filter(username=username, password=password).first()
if user:
# 如果用户名密码正确
token = get_random_token(username)
models.Token.objects.update_or_create(defaults={"token_code": token}, user=user)
res["token"] = token
else:
res["code"] = 1
res["error"] = "用户名或密码错误"
return Response(res)

定义一个认证类

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed class MyAuth(BaseAuthentication):
def authenticate(self, request):
if request.method in ["POST", "PUT", "DELETE"]:
request_token = request.data.get("token", None)
if not request_token:
raise AuthenticationFailed('缺少token')
token_obj = models.Token.objects.filter(token_code=request_token).first()
if not token_obj:
raise AuthenticationFailed('无效的token')
return token_obj.user.username, None
else:
return None, None

视图级别认证

class CommentViewSet(ModelViewSet):

    queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth, ]

全局级别认证

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

权限

只有VIP用户才能看的内容。

自定义一个权限类

# 自定义权限
class MyPermission(BasePermission):
message = 'VIP用户才能访问' def has_permission(self, request, view):
"""
自定义权限只有VIP用户才能访问
"""
# 因为在进行权限判断之前已经做了认证判断,所以这里可以直接拿到request.user
if request.user and request.user.type == 2: # 如果是VIP用户
return True
else:
return False

视图级别配置

class CommentViewSet(ModelViewSet):

    queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
authentication_classes = [MyAuth, ]
permission_classes = [MyPermission, ]

全局级别设置

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

限制

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

自定义限制类

VISIT_RECORD = {}
# 自定义限制
class MyThrottle(object): def __init__(self):
self.history = None def allow_request(self, request, view):
"""
自定义频率限制60秒内只能访问三次
"""
# 获取用户IP
ip = request.META.get("REMOTE_ADDR")
timestamp = time.time()
if ip not in VISIT_RECORD:
VISIT_RECORD[ip] = [timestamp, ]
return True
history = VISIT_RECORD[ip]
self.history = history
history.insert(0, timestamp)
while history and history[-1] < timestamp - 60:
history.pop()
if len(history) > 3:
return False
else:
return True def wait(self):
"""
限制时间还剩多少
"""
timestamp = time.time()
return 60 - (timestamp - self.history[-1])

视图使用

class CommentViewSet(ModelViewSet):

    queryset = models.Comment.objects.all()
serializer_class = app01_serializers.CommentSerializer
throttle_classes = [MyThrottle, ]

全局使用

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

使用内置限制类

from rest_framework.throttling import SimpleRateThrottle

class VisitThrottle(SimpleRateThrottle):

    scope = "xxx"

    def get_cache_key(self, request, view):
return self.get_ident(request)

全局配置

# 在settings.py中设置rest framework相关配置项
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
# "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
"DEFAULT_THROTTLE_CLASSES": ["app01.utils.VisitThrottle", ],
"DEFAULT_THROTTLE_RATES": {
"xxx": "5/m",
}
}

Django REST framework基础:认证、权限、限制的更多相关文章

  1. Django REST framework 之 认证 权限 限制

    认证是确定你是谁 权限是指你有没有访问这个接口的权限 限制主要是指限制你的访问频率 认证 REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 接下类我们就自己 ...

  2. Django Rest framework 之 认证

    django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...

  3. Django rest framework 基础

    01: Django rest framework 基础 ​ ​ 1.1 什么是RESTful 1. REST与技术无关,代表的是一种软件架构风格(REST是Representational Stat ...

  4. django rest framework用户认证

    django rest framework用户认证 进入rest framework的Apiview @classmethod def as_view(cls, **initkwargs): &quo ...

  5. Django REST framework基础:视图和路由

    DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Dj ...

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

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

  7. Django Rest framework基础使用之 serializer

    rest-framework文档地址:http://www.django-rest-framework.org/ Django Rest framework是一个非常强大且灵活的工具包,用于构建web ...

  8. Django REST framework基础:版本、认证、权限、限制

    1  认证.权限和限制 2  认证 2.1  自定义Token认证 2.1.1  表 2.1.2  定义一个登录视图: 2.1.3  定义一个认证类 2.1.4  视图级别认证 2.1.5  全局级别 ...

  9. Django Rest framework基础使用之View:APIView, mixins, generic, viewsets

    先看一张图,对DRF的各个APIView,Mixin,Viewset等有个基本印象: 具体使用方法: 1.APIView: DRF 的API视图 有两种实现方式: 一种是基于函数的:@api_view ...

随机推荐

  1. python中的None

    python中的None python中的None就相较于Java中的Null.python中就没有所谓的NULL.网络上很多的时候说的"python的Null"这个说法本身就是不 ...

  2. Django知识点

    一.Django        pip3 install django            C:\Python35\Scripts        # 创建Django工程    django-adm ...

  3. Spring Cloud中的负载均衡策略

    在上篇博客(Spring Cloud中负载均衡器概览)中,我们大致的了解了一下Spring Cloud中有哪些负载均衡器,但是对于负载均衡策略我们并没有去详细了解,我们只是知道在BaseLoadBal ...

  4. [linux]CentOS 7 下安装 RabbitMQ

    简介 RabbitMQ 是实现了高级消息队列协议(AMQP)的开源消息代理软件.RabbitMQ 服务器是用 Erlang 语言编写的,所以下面要安装 RabbitMQ 需要安装 Erlang. 一. ...

  5. SpringBoot技术栈搭建个人博客【项目准备】

    前言:很早之前就想要写一个自己的博客了,趁着现在学校安排的实习有很多的空档,决定把它给做出来,也顺便完成实习的任务(搞一个项目出来...) 需求分析 总体目标:设计一套自适应/简洁/美观/易于文章管理 ...

  6. leetcode — merge-sorted-array

    import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/merge-sorted-array/ * * * G ...

  7. log4j2 使用纪要

    简介 Apache Log4j 2 是Log4j 的升级版,在该版本实现中,日志的处理流程及效率有了显著提升. 此外新版本也合入了一些logback日志框架体系的一些改进点. 关键特性 API分离,接 ...

  8. python学习第三讲,python基础语法之注释,算数运算符,变量.

    目录 python学习第三讲,python基础语法之注释,算数运算符,变量. 一丶python中的基础语法,注释,算数运算符,变量 1.python中的注释 2.python中的运算符. 3.pyth ...

  9. Docker系列03—Docker 基础入门

    本文收录在容器技术学习系列文章总目录 1.概念介绍 1.1 容器 1.1.1 介绍 容纳其它物品的工具,可以部分或完全封闭,被用于容纳.储存.运输物品.物体可以被放置在容器中,而容器则可以保护内容物. ...

  10. Spring Boot 2.x (八):日志框架的使用

    我们为啥要用日志? 最初我们开始接触Java的时候,我们通常会使用System.out.println()将我们想要知道的信息打印到控制台. 但是,如果在服务器上我们去运行我们的Java程序,这个时候 ...