Django REST framework基础:认证、权限、限制
认证、权限和限制
身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制。然后 权限 和 限制 组件决定是否拒绝这个请求。
简单来说就是:
认证确定了你是谁
权限确定你能不能访问某个接口
限制确定你访问某个接口的频率
认证
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基础:认证、权限、限制的更多相关文章
- Django REST framework 之 认证 权限 限制
认证是确定你是谁 权限是指你有没有访问这个接口的权限 限制主要是指限制你的访问频率 认证 REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案. 接下类我们就自己 ...
- Django Rest framework 之 认证
django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...
- Django rest framework 基础
01: Django rest framework 基础 1.1 什么是RESTful 1. REST与技术无关,代表的是一种软件架构风格(REST是Representational Stat ...
- django rest framework用户认证
django rest framework用户认证 进入rest framework的Apiview @classmethod def as_view(cls, **initkwargs): &quo ...
- Django REST framework基础:视图和路由
DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Dj ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限
开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他 ...
- Django Rest framework基础使用之 serializer
rest-framework文档地址:http://www.django-rest-framework.org/ Django Rest framework是一个非常强大且灵活的工具包,用于构建web ...
- Django REST framework基础:版本、认证、权限、限制
1 认证.权限和限制 2 认证 2.1 自定义Token认证 2.1.1 表 2.1.2 定义一个登录视图: 2.1.3 定义一个认证类 2.1.4 视图级别认证 2.1.5 全局级别 ...
- Django Rest framework基础使用之View:APIView, mixins, generic, viewsets
先看一张图,对DRF的各个APIView,Mixin,Viewset等有个基本印象: 具体使用方法: 1.APIView: DRF 的API视图 有两种实现方式: 一种是基于函数的:@api_view ...
随机推荐
- 【JVM虚拟机】(2)---GC 算法与种类
GC 算法与种类 对于垃圾收集(GC), 我们需要考虑三件事情:哪些内存需要回收?如何判断是垃圾对象?垃圾回收算法有哪些? 一.GC的工作区域 1.不是GC的工作区域 (1)程序计数器.虚拟机栈和本地 ...
- Web系统大规模并发:电商秒杀与抢购-----面试必问
一.大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战.如果Web系统不做针对性的优化,会轻而易举地陷入到异常状态.我们现在 ...
- C++、Java语法差异对照表
C++.Java语法差异对照表 C++ and Java Syntax Differences Cheat Sheet First, two big things--the main function ...
- 使用Spring Cloud搭建高可用服务注册中心
我们需要的,不仅仅是一个服务注册中心而已,而是一个高可用服务注册中心. 上篇博客[使用Spring Cloud搭建服务注册中心]中我们介绍了如何使用Spring Cloud搭建一个服务注册中心,但是搭 ...
- 前端笔记之JavaScript(九)定时器&JSON&同步异步/回调函数&函数节流&call/apply
一.快捷位置和尺寸属性 DOM已经提供给我们计算后的样式,但是还是觉得不方便,因为计算后的样式属性值都是字符串类型. 不能直接参与运算. 所以DOM又提供了一些API:得到的就是number类型的数据 ...
- 阿里注册中心nacos使用整合Dubbo-原创
阿里注册中心nacos是今年开源的框架,一开始以为就是个zk.后面看了图才明白他对标的竟然是consul\eureka,最重要是完美支持dubbo.我想今年开源它也是别有用意 .(目前nacos0.7 ...
- Android总结篇系列:Activity启动模式(lauchMode)
本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些理解,在此感谢原作者. 文章地址: http://blog.csdn.net/l ...
- Java——final关键字
前言 Java中的关键字final的含义通常为"这是无法改变的".下面将介绍final用于修饰数据.方法和类的这三种情况. final数据 许多编程语言都有某种方法,来向告诉编译器 ...
- DataTable转换成List集合,传递到HTML页面
public string GetPwd(string str) { var dt= bll.Gets(str); List<string> list = new List<stri ...
- Php中的goto用法
我们先举个简单示例: <?php goto LABEL; //这个标签自定义 echo '乔峰'; LABEL: echo '鸠摩智'; 以上例程会输出:鸠摩智 解释:goto 操作符可以用来跳 ...