本篇随笔在 "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 自定义(认证、权限、访问频率)组件的更多相关文章

  1. Django REST framework 之 认证 权限 限制

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

  2. Django Rest framework 之 认证

    django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...

  3. django rest framework用户认证

    django rest framework用户认证 进入rest framework的Apiview @classmethod def as_view(cls, **initkwargs): &quo ...

  4. Django rest framework 的认证流程(源码分析)

    一.基本流程举例: urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', views.HostView.as_view() ...

  5. rest-framework框架——认证、权限、频率组件

    一.rest-framework登录验证 1.models.py添加User和Token模型 class User(models.Model): name = models.CharField(max ...

  6. Rest_Framework之认证、权限、频率组件源码剖析

    一:使用RestFramwork,定义一个视图 from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet ...

  7. DRF Django REST framework 之 认证组件(五)

    引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任 ...

  8. DRF 认证 权限 视图 频率

    认证组件 使用:写一个认证类,继承BaseAuthentication 在类中写authenticate方法,把request对象传入 能从request对象中取出用户携带的token根据token判 ...

  9. restframework 认证、权限、频率组件

    一.认证 1.表的关系 class User(models.Model): name = models.CharField(max_length=32) pwd = models.CharField( ...

随机推荐

  1. 用C++实现一个Quaternion类

    提要 四元素是游戏开发中经常使用的用于处理旋转的数学工具,以下就用C++来实现一个四元素类.參考Unity中四元素的接口. 假设没有看之前的 彻底搞懂四元数. 建议先看一下. 代码清单 Quatern ...

  2. ios ionic 装平台 笔记

    1.安装cnpm : npm install -g cnpm --registry=https://registry.npm.taobao.org 2.An error occurred when I ...

  3. puppet开源的软件自动化配置和部署工具——本质就是CS,服务端统一管理配置

    1.  概述 puppet是一个开源的软件自动化配置和部署工具,它使用简单且功能强大,正得到了越来越多地关注,现在很多大型IT公司均在使用puppet对集群中的软件进行管理和部署,如google利用p ...

  4. 36.面板Ext.Panel使用

    转自:https://www.cnblogs.com/linjiqin/archive/2011/06/22/2086620.html 面板Ext.Panel使用 概要 1.Ext.Panel概述 2 ...

  5. SpringBoot 启动定时任务

    再项目中大多会使用定时任务来定时执行一些操作,如:文件迁移,备份等等.今天就来跟大家一起学习下如何在SpringBoot中创建定时任务. 1.新建SpringBoot项目,或在原有的项目上添加(不知道 ...

  6. Django-CKeditor使用笔记

    1. 安装django-ckeditor $ pip install django-ckeditor 2. 在setting中,添加ckeditor , ckeditor_uploader 到INST ...

  7. 【LeetCode】 -- 68.Text Justification

    题目大意:给定一个数组容器,里面存有很多string: 一个int maxWith.让你均匀安排每一行的字符串,能够尽可能的均匀. 解题思路:字符串+贪心.一开始想复杂了,总觉的题意描述的不是很清楚, ...

  8. python--9、并发之多进程应用

    multiprocessing模块 想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.Python提供了multiprocessing.  ...

  9. TensorFlow学习---入门(一)-----MNIST机器学习

    参考教程:http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html 数据下载地址:http://wiki.jikexueyuan.com ...

  10. JS——try catch throw

    本例检测输入变量的值.如果值是错误的,会抛出一个异常(错误).catch 会捕捉到这个错误,并显示一段自定义的错误消息: <script> function myFunction() { ...