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

接下类我们就自己动手实现一个基于Token的认证方案:
自定义Token认证
表
定义一个用户表和一个保存用户Token的表:
# 用户表
class UserInfo(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
vip = models.BooleanField(default=False)
token = models.CharField(max_length=128, null=True, blank=True)
视图:
定义一个登陆视图
class LoginView(APIView):
def post(self, request):
name = request.data.get('name')
pwd = request.data.get('pwd')
if name and pwd:
user_obj = models.UserInfo.objects.filter(name=name, pwd=pwd).first()
if user_obj:
# 登陆成功
# 生成token(时间戳 + Mac地址)
token = uuid.uuid1().hex
# 1.保存在用户表中
user_obj.token = token
user_obj.save()
# 2.给用户返回
return Response({'error_no': 0, 'token': token}) else:
# 用户名或密码错误
return Response({'error_no': 1, 'error': '用户名或密码错误'})
else:
return Response('无效的参数')
定义一个认证类
from rest_framework.authentication import BaseAuthentication
from auth_demo import models
from rest_framework.exceptions import AuthenticationFailed # 抛错时使用 class MyAuth(BaseAuthentication): def authenticate(self, request):
token = request.query_params.get('token')
if token:
# 如果请求的URL中携带了token参数
user_obj = models.UserInfo.objects.filter(token=token).first()
if user_obj:
# token是有效的
return user_obj, token # request.user, request.auth
else:
raise AuthenticationFailed('无效的token')
else:
raise AuthenticationFailed('请求的URL中必须携带token参数')
视图级别的认证:
class TestAuthView(APIView):
authentication_classes = [MyAuth, ] # 局部配置认证
permission_classes = [MyPermission, ] def get(self, request):
print(request.user.name)
print(request.auth)
return Response('这个视图里面的数据只有登录后才能看到!')
全局级别认证
# 在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):
if not request.auth: # 用户登录确认
return False # 如果你是VIP才有权限访问
# request.user:当前经过认证的用户对象
if request.user.vip:
return True
else:
# 如果不是VIP就拒绝范围跟
return False
视图级别认证:
class TestAuthView(APIView):
authentication_classes = [MyAuth, ] # 局部配置认证
permission_classes = [MyPermission, ] # 权限局部认证 def get(self, request):
print(request.user.name)
print(request.auth)
return Response('这个视图里面的数据只有登录后才能看到!')
全局级别设置
# 在settings.py中设置rest framework相关配置项
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
"DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
}
限制
自定义一个限制访问的类
import time
"""
自定义一个限制
"""
# 创建一个空的字典
visit = {} class BaseThrottle(object):
def __init__(self):
self.history = None def allow_request(self, request, view):
ip = request.META.get('REMOTE_ADDR') # 获取用户的ip地址
now = time.time() # 获取当前时间 if ip not in visit: # 第一次进来的时候 字典中没有以ip为key的键值对
visit[ip] = [] # 创建一个以ip为key的键值对
history = visit[ip] # 如果不是第一次访问的话 获取一下以ip为key的对应的值
self.history = history # 因为wait方法中也会用到history的值,所以把history升级成类属性
while history and now - history[-1] > 10: # 循环判断一下 如果当前时间与history里面的最先插入的时间大于10秒
history.pop() # 就删除最后的先插入的那个数据
if len(history) >= 3: # 如果10秒内history里面的时间戳大于3个,表示查询过于频繁,限制一下,返回false
return False
else: # 如果10秒钟内没有三个时间戳,再来访问的话是可以的,记录一下当前访问的时间戳
history.insert(0, now)
return True def wait(self): # 这个方法主要是提示用户等待时间的
now = time.time() # 获取当前时间
return self.history[-1]+10 - now # 最早访问的时间减去当前时间
使用
局部使用
class TestView(APIView):
authentication_classes = [Myauth, ] # 用户身份验证
permission_classes = [Permissions, ] # 用户权限验证
throttle_classes = [BaseThrottle, ] # 用户访问频率限制 def get(self, request):
print(request.user)
print(request.auth)
return Response("这是会员才可以看到的画面")
全局使用
# 在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 之 认证
django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...
- django rest framework用户认证
django rest framework用户认证 进入rest framework的Apiview @classmethod def as_view(cls, **initkwargs): &quo ...
- Django rest framework 的认证流程(源码分析)
一.基本流程举例: urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', views.HostView.as_view() ...
- DRF Django REST framework 之 认证组件(五)
引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任 ...
- Django REST Framework之认证组件
什么是认证 认证即需要知道是谁在访问服务器,需要有一个合法身份.认证的方式可以有很多种,例如session+cookie.token等,这里以token为例.如果请求中没有token,我们认为这是未登 ...
- Django Rest Framework之认证
代码基本结构 url.py: from django.conf.urls import url, include from web.views.s1_api import TestView urlpa ...
- 基于django rest framework做认证组件
先导入要用到的类 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions ...
- 【django后端分离】Django Rest Framework之认证系统之redis数据库的token认证(token过期时间)
1:登录视图 redis_cli.py文件: import redis Pool= redis.ConnectionPool(host='localhost',port=6379,decode_res ...
- 源码剖析Django REST framework的认证方式及自定义认证
源码剖析Django REST framework的认证方式 在前面说过,请求到达REST framework的时候,会对request进行二次封装,在封装的过程中会对客户端发送过来的request封 ...
随机推荐
- centos7 源码编译安装 php
准备工作 下载 PHP 源码包并解压 $ wget https://www.php.net/distributions/php-7.2.19.tar.bz2 $ yum -y install bzip ...
- semantic-ui的表单使用
semantic-ui 的表单使用 最近找了一款ui库,jquery可以使用的.可以进行个性化定制,感觉还不错. 现状 简单阐述下该ui的现状吧,目前止步于2.4的版本,github商讨了一波.大致是 ...
- sql修改表名字段名
修改字段: ALTER TABLE user_info CHANGE NAME name VARCHAR(10); 修改表名alter TABLE user_role RENAME user_info ...
- css 文本单行显示溢出时出现省略号 多行显示溢出时出现省略号 首行缩进
一.文本单行显示溢出时出现省略号 二.文本多行显示溢出时出现省略号(这种样式只能在webkit和移动端使用,包括小程序,不能设置固定高度) 三.首行缩进两字符 text-indent: 2em; 四. ...
- sqlite3中 timestamp使用
timestamp使用 一. timestamp两种属性:自动初始化: 此行为只在第一次写入数据时,怎么把时间设为当前时间. (DEFAULT CURRENT_TIMESTAMP)自动更新: 此行为在 ...
- 【leetcode】 463. Island Perimeter
题目: 以二维数组形式表示坐标岛屿,求边长. 例子: [[0,1,0,0], [1,1,1,0], [0,1,0,0], [1,1,0,0]] Answer: 16 Explanation: The ...
- ipc - System V 进程间通信机制
SYNOPSIS 总览 # include <sys/types.h> # include <sys/ipc.h> # include <sys/msg.h> # ...
- puppet工简介一
puppet简介一 puppet工作原理 puppet 是一个配置管理工具, 典型的, puppet 是一个 C/S 结构, 当然,这里的 C 可以有很多,因 此,也可以说是一个星型结构. 所有的 p ...
- The Python Challenge 闯关笔记
The Python Challenge : http://www.pythonchallenge.com/ Level 0: 看提示图片中为2**38,计算值为274877906944. Hint: ...
- 微信开发企业支付到银行卡PHP
微信开发企业支付到银行卡 功能详解 不会的朋友可以加我QQ:344902511先发个微信支付官方链接你查看https://pay.weixin.qq.com/wiki/doc/api/tools/mc ...