Django REST framework 自定义(认证、权限、访问频率)组件
本篇随笔在 "Django REST framework 初识" 基础上扩展
一、认证组件
# models.py
class Account(models.Model):
"""用户表"""
username = models.CharField(verbose_name="用户名", max_length=, unique=True)
password = models.CharField(verbose_name="密码", max_length=) class UserToken(models.Model):
"""用户Token表"""
user = models.OneToOneField(to="Account")
token = models.CharField(max_length=, unique=True)
当然也可以使用django自带的 auth_user 表来保存用户信息,Token表一对一关联这张表或者继承这张表:
from django.contrib.auth.models import User
class Token(models.Model):
user = models.OneToOneField(User)
token = models.CharField(max_length=64) from django.contrib.auth.models import AbstractUser
class Token(AbstractUser):
token = models.CharField(max_length=64)
auth.py
from rest_framework import authentication
from rest_framework import exceptions
from api import models class UserTokenAuth(authentication.BaseAuthentication):
"""用户身份认证"""
def authenticate(self, request):
token = request.query_params.get("token")
obj = models.UserToken.objects.filter(token=token).first()
if not obj:
raise exceptions.AuthenticationFailed({"code": 200, "error": "用户身份认证失败!"})
else:
return (obj.user.username, obj)
Views.py
import time
import hashlib
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from django.core.exceptions import ObjectDoesNotExist
from api import models
from appxx import serializers
from appxx.auth.auth import UserTokenAuth class LoginView(APIView):
"""
用户认证接口
"""
def post(self, request, *args, **kwargs):
rep = {"code": 1000}
username = request.data.get("username")
password = request.data.get("password")
try:
user = models.Account.objects.get(username=username, password=password)
token = self.get_token(user.password)
rep["token"] = token
models.UserToken.objects.update_or_create(user=user, defaults={"token": token})
except ObjectDoesNotExist as e:
rep["code"] = 1001
rep["error"] = "用户名或密码错误"
except Exception as e:
rep["code"] = 1002
rep["error"] = "发生错误,请重试"
return Response(rep) @staticmethod
def get_token(password):
timestamp = str(time.time())
md5 = hashlib.md5(bytes(password, encoding="utf-8"))
md5.update(bytes(timestamp, encoding="utf-8"))
return md5.hexdigest() class BookViewSet(viewsets.ModelViewSet):
authentication_classes = [utils.AuthToken]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
urls.py
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from appxx import views router = DefaultRouter()
router.register(r"books", views.BookViewSet)
router.register(r"publishers", views.PublisherViewSet) urlpatterns = [
url(r"^login/$", views.LoginView.as_view(), name="login"),
url(r"", include(router.urls)),
]
局部认证(哪个视图类需要认证就在哪加上)
如果需要每条URL都加上身份认证,那么是不是views.py中每个对应的类视图都加上authentication_classes呢?那多麻烦,有没有更简便的方法?请看下面如何设置全局的认证。
全局认证
在settings.py中设置:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["appxx.utils.TokenAuthentication",],
# "UNAUTHENTICATED_USER": None, # 匿名,request.user = None
# "UNAUTHENTICATED_TOKEN": None, # 匿名,request.auth = None
}
可以看到,AuthToken 就是 BookViewSet 用到的 authentication_classes,这样views.py中的每个类视图都不需要加 authentication_classes 了;每条URL都必须经过此认证才能访问。
class BookViewSet(viewsets.ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer class PublisherViewSet(viewsets.ModelViewSet):
queryset = models.Publisher.objects.all()
serializer_class = serializers.PublisherSerializer
二、权限组件
修改模型表,给用户加上用户类型字段:
class UserProfile(models.Model):
username = models.CharField(verbose_name="用户名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
user_type_choices = ((1, "管理员"), (2, "普通用户"), (3, "VIP"))
user_type = models.SmallIntegerField(choices=user_type_choices, default=2)
class UserTypePermission(permissions.BasePermission):
"""权限认证"""
message = "只有管理员才能访问" def has_permission(self, request, view):
user = request.user
try:
user_type = models.UserProfile.objects.filter(username=user).first().user_type
except AttributeError:
return False
if user_type == 1:
return True
else:
return False
局部权限
class BookViewSet(viewsets.ModelViewSet):
permission_classes = [utils.UserTypePermission]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
全局权限
REST_FRAMEWORK = {"DEFAULT_PERMISSION_CLASSES": ["appxx.utils.UserTypePermission",],
}
三、访问频率组件
import time
visit_record = {} # 可以放在redis中
class IpRateThrottle(object):
"""60s内只能访问3次"""
def __init__(self):
self.history = None
def allow_request(self, request, view):
ip = request.META.get("REMOTE_ADDR") # 获取用户IP
current_time = time.time()
if ip not in visit_record: # 用户第一次访问
visit_record[ip] = [current_time]
return True
history = visit_record.get(ip)
self.history = history
while history and history[-1] < current_time - 60:
history.pop()
if len(history) < 3:
history.insert(0, current_time)
return True
# return True # 表示可以继续访问
# return False # 表示访问频率太高,被限制
def wait(self):
"""还需要等多久才能访问"""
current_time = time.time()
return 60 - (current_time - self.history[-1])
局部节流
class BookViewSet(viewsets.ModelViewSet):
throttle_classes = [IpRateThrottle]
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
全局节流
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES": ["appxx.utils.IpRateThrottle",],
}
PS:
匿名用户:无法控制,因为用户可以换代理IP
登录用户:如果有很多账号,也无法限制
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用户认证
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() ...
- rest-framework框架——认证、权限、频率组件
一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...
- Rest_Framework之认证、权限、频率组件源码剖析
一:使用RestFramwork,定义一个视图 from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet ...
- DRF Django REST framework 之 认证组件(五)
引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任 ...
- DRF 认证 权限 视图 频率
认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...
- restframework 认证、权限、频率组件
一.认证 1.表的关系 class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField( ...
随机推荐
- Android离线语音识别(PocketSphinx)
近期做项目.用到离线语音识别.整了好久,查了好多方法.最终完毕.网上资料有点乱,并且大部分就是那几个人写的.一群人转!以下我总结一下.也为后来人行个方便. 关于环境配置我就不多说了.我就是依照这个教程 ...
- 技术架构model
- c++ 编译器会绕过拷贝构造函数
C++ primer P442 P447:在拷贝初始化过程中,编译器可以跳过拷贝构造函数,直接创建对象.即,编译器允许将下面的代码 "; //1 改写为 "); //2 由于str ...
- RK平台Android4.4 添加一个新的遥控器支持以及添加特殊按键【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/52904063 版权声明:本文为博主原创文章,未经博主允许不得转载. 瑞芯微平台 ...
- tiny4412 裸机程序 八、重定位到DRAM及LCD实验【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37407423 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 一 ...
- bzoj4889
http://www.lydsy.com/JudgeOnline/problem.php?id=4889 人傻常数大 bzoj上跑不过 洛谷上能过两到三个点 我写的是树套树啊 怎么跑的比分块还慢 每次 ...
- canvas做的时钟,学习下
canvas标签只是图形容器,您必须使用脚本来绘制图形. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性.——获取上下文对象. getContext(" ...
- 洛谷P1478 陶陶摘苹果(升级版)
题目数据范围小,开两个数组手写冒泡应该也能过,不过和之前在牛客上的一题类似用结构体数组就好了,主要是注意用结构体数组的排序 题目 题目描述 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果 ...
- Django day28 频率组件,解析器
一:频率组件: 1.频率是什么? 节流,访问控制 2. (1)内置的访问频率控制类SimpleRateThrottle (2)写一个类,继承SimpleRateThrottle class MyThr ...
- $stylus美化$
一直在用洛谷 当然不一定是洛谷 其他的网站也可以用 比如说codeforces 还是决定要美化一波 首先去找一个插件 叫做 stylus stylus下载的很多 我不想过多说明. Google和QQ浏 ...