Django REST Framework 认证 - 权限 - 限制
一. 认证
(你是谁?)
REST framework 提供了一些开箱即用的身份验证方案,并且还允许你实现自定义方案。

自定义Token认证
第一步 : 建表>>>>
定义一个用户表和一个保存用户Token的表
class UserInfo(models.Model):
username = models.CharField(max_length=16)
password = models.CharField(max_length=32)
type = models.SmallIntegerField(
choices=((0, '普通用户'), (1, 'VIP用户')),
default=0
) class Token(models.Model):
user = models.OneToOneField(to='UserInfo')
token_code = models.CharField(max_length=128)
第二步: 定义一个登陆视图 >>>>
from rest_framework.views import APIView
from app2 import models
from rest_framework.response import Response
import hashlib, time def get_random_token(username):
"""
根据用户名和时间戳生成随机token
"""
timestamp = str(time.time())
m = hashlib.md5(bytes(username, encoding="utf-8"))
m.update(bytes(timestamp, encoding="utf-8"))
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
from app2 import models class MyAuth(BaseAuthentication):
def authenticate(self, request):
# if request.method in ["POST", "PUT", "DELETE"]: # 如果在表单中需要判断请求方式 由于表单是post请求,所以获取token 的方式为 request.data.get("token")
# request.query_params为url中的参数
request_token = request.query_params.get("token", None)
if not request_token:
raise AuthenticationFailed('q.缺少token') token_obj = models.Token.objects.filter(token_code=request_token).first()
if not token_obj:
raise AuthenticationFailed("无效的Token")
# token_obj.user 通过token这张表的对象和user这个关联字段 找到 UserInfo表的对象及当前用户对象
return token_obj.user, request_token # 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才能看到的东西
第一步: 自定义一个权限类
"""
自己动手写一个权限组件
"""
from rest_framework.permissions import BasePermission class MyPermission(BasePermission): message = '只有VIP才能访问' def has_permission(self, request, view):
# 认证类中返回了token_obj.user, request_token
# request.auth 等价于request_token
if not request.auth:
return False
# request.user为当前用户对象
if request.user and request.user.type == 1: # 如果是VIP用户
print("requ", request.user, type(request.user))
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", ]
}
三. 控制
(你一分钟能干多少次?)**好像有点污~~
第一步: 自定义限制类 >>>>
import time # from rest_framework.throttling import
visit_record = {} class MyThrottle(object): def __init__(self):
self.history = None def allow_request(self, request, view):
# 拿到当前的请求的ip作为访问记录的 key
ip = request.META.get('REMOTE_ADDR')
# 拿到当前请求的时间戳
now = time.time()
if ip not in visit_record:
visit_record[ip] = []
# 把当前请求的访问记录拿出来保存到一个变量中
history = visit_record[ip]
self.history = history
# 循环访问历史,把超过10秒钟的请求时间去掉
while history and now - history[-1] > 10:
history.pop()
# 此时 history中只保存了最近10秒钟的访问记录
if len(history) >= 3:
return False
else:
# 判断之前有没有访问记录(第一次来)
self.history.insert(0, now)
return True def wait(self):
"""告诉客户端还需等待多久"""
now = time.time()
return self.history[-1] + 10 - now # history = ['9:56:12', '9:56:10', '9:56:09', '9:56:08'] # '9:56:18' - '9:56:12' # history = ['9:56:19', '9:56:18', '9:56:17', '9:56:08'] # 最后一项到期的时间就是下一次允许请求的时间 # 最后一项到期的时间:now - history[-1] > 10 # 最后一项还剩多少时间过期
# history[-1] + 10 - now
第二步: 使用 >>>
视图中使用
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",
}
}
看源码:
1.认证流程






2. 权限





Django REST Framework 认证 - 权限 - 限制的更多相关文章
- Django REST framework认证权限和限制和频率
认证.权限和限制 身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制.然后 权限 和 限制 组件决定是否拒绝这个请求. 简单来说就是: 认证确定了你是谁 权限确定你能不 ...
- Django REST framework认证权限和限制 源码分析
1.首先 我们进入这个initial()里面看下他内部是怎么实现的. 2.我们进入里面看到他实现了3个方法,一个认证,权限频率 3.我们首先看下认证组件发生了什么 权限: 啥都没返回,self.per ...
- Django Rest Framework(认证、权限、限制访问频率)
阅读原文Django Rest Framework(认证.权限.限制访问频率) django_rest_framework doc django_redis cache doc
- Django Rest framework 之 权限
django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) django res ...
- 04 Django REST Framework 认证、权限和限制
目前,我们的API对谁可以编辑或删除代码段没有任何限制.我们希望有更高级的行为,以确保: 代码片段始终与创建者相关联. 只有通过身份验证的用户可以创建片段. 只有代码片段的创建者可以更新或删除它. 未 ...
- django 之(三) --- 认证|权限
用户模块 登陆注册1:Django2.0 [ 1:N ] user/url.py from django.urls import path from user.views0 import UserT ...
- rest framework 认证 权限 频率
认证组件 发生位置 APIview 类种的 dispatch 方法执行到 initial 方法 进行 认证组件认证 源码位置 rest_framework.authentication 源码内部需要 ...
- Django Rest Framework之权限
基本代码结构 url.py: from django.conf.urls import url, include from app import views urlpatterns = [ url(r ...
- Django REST framework - 认证
目录 认证 DRF 5种验证方式 如何确定身份验证? 设置身份验证方案 案例: 基于自定义Token认证 第一步: 定义一个用户表和一个保存用户Token的表 第二步: 定义一个登陆视图 第三步定义一 ...
随机推荐
- 使用maven创建springMVC时返回页面报错
这是由于你的 Maven 编译级别是 jdk1.5 或以下,而你导入了 jdk1.6 以上的依赖包 解决办法: <build> <finalName></finalNam ...
- android 异常解决方案汇总
1)异常:Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法) 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来. 2.将引用的第三方 ...
- phpEXCEL如何设置单元格格式为百分比
$objExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_S ...
- C/C++ 获取文件夹下的所有文件列表
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51009608 提供一段C/C++代码示 ...
- python 中的一些小命令
- 6 Javascript:函数
函数 函数是面向任务的. 当我们面临一个须要可问题的时候.往往无处下手.这时候.须要将问题分解为多个任务,从而逐一击破. 这里就须要函数的帮助. 语法 function Name() { Body() ...
- 关于部门后端所有转向java前初步设想
Java服务有些什么形式?眼下来看主要是下面几类: 1. 执行在Web应用server的Servlet 2. Thrift.PB.Avro等相似框架写的java服务 3. WebService( ...
- RecyclerView的点击事件
RecyclerView 一.简单介绍 这个是谷歌官方出的控件.使我们能够很easy的做出列表装的一个控件,当然recyclerview的功能不止这些,它还能够做出瀑布流的效果,这是一个很强大的控件, ...
- linux中设置TAB键的宽度
对于编程的人员来说,常常须要排版代码,这时候就须要TAB键,但TAB键的宽度太大,非常有可能代码太长,延伸到下一行,这个时候你就须要设置TAB键的宽度了. linux下设置TAB键的宽度,做法例如以下 ...
- 造个简单的轮子倒是不难,但可用性健壮性高到qt这样全世界都在用,就几乎不可能了
造个简单的轮子倒是不难,但可用性健壮性高到qt这样全世界都在用,就几乎不可能了比如自己写个事件循环实现信号槽,还真不难,我这边的架构里就这么搞了个仿osgi的事件总线嵌入式实时操作系统上能用的大型gu ...