认证是确定你是谁

权限是指你有没有访问这个接口的权限

限制主要是指限制你的访问频率

认证

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",
}
}

最新文章

  1. BZOJ4455: [Zjoi2016]小星星
  2. go:windows下用sublime Text搭建go语言开发环境
  3. java,js,jstl,EL的简单交互
  4. BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)
  5. throw跟throws关键字
  6. 向hive上传数据时,中文乱码
  7. java语言中一些使用的小技巧(区别于c++)
  8. 关于e820cycles参数
  9. bjfu1299 stl使用
  10. wordpress修改固定链接及修改链接后链接提示404错误的解决办法
  11. linux 文件在磁盘上的表示
  12. Sql Server Profiler跟踪死锁
  13. Oracle Statspack报告中各项指标含义详解~~学习性能必看!!!
  14. CodeForces 573A Bear and Poker
  15. 成都大数据Hadoop与Spark技术培训班
  16. nodeValue的兼容问题
  17. Python学习笔记007_图形用户界面[EasyGui][Tkinter]
  18. ADB——修改手机默认参数
  19. Win7 VS2017编译Blender2.79
  20. 使用winsw部署spring boot jar 项目

热门文章

  1. python 链接mysql 修改查询删除语句
  2. Exchange 2010的部署
  3. 将数据库模型放入到.Net Core的类库中
  4. java 并发编程lock使用详解
  5. SpringBoot测试类启动错误 java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
  6. 下载 Eclipse 免安装版~
  7. Java 判断是否为回文字符串
  8. TanksWar(坦克大战三维、二维版以及90版)
  9. 自动化运维——HelloWorld(一)
  10. Vim搜索关键字