Django Rest Framework-认证、限制、节流

认证、权限、节流

身份验证是将传入请求与一组标识凭据(例如请求来自的用户或其签名的令牌)相关联的机制。然后 权限 和 限制 组件决定是否拒绝这个请求。

简单来说就是:

认证确定了你是谁 (认证)

权限确定你能不能访问某个接口 (权限)

节流确定你访问某个接口的频率 (节流)

认证

示例:

models

from django.db import models
# Create your models here.

class User(models.Model):
    level_choices = (
        (1, '普通用户'),
        (2, 'VIP'),
        (3, 'SVIP'),
    )
    level = models.IntegerField(choices=level_choices)
    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)

    def __str__(self):
        return self.username


class UserToken(models.Model):
    user = models.OneToOneField(to='User', on_delete=models.CASCADE)
    token = models.CharField(max_length=64)

    def __str__(self):
        return self.user.get_level_display()
View Code

 

url

from django.urls import path
from app01 import views

urlpatterns = [
    path('api/v1/auth', views.AuthView.as_view()),
]
View Code

 

view

from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework import exceptions
from app01 import models
from app01.utils.auth import UserAuth
import time
import hashlib


def get_token(user):
    m = hashlib.md5(bytes(user, encoding='utf-8'))
    ctime = str(time.time())
    m.update(bytes(ctime, encoding='utf-8'))

    return m.hexdigest()


class AuthView(APIView):
    """
    用于验证登录
    """
    authentication_classes = []

    def post(self, request, *args, **kwargs):

        # 返回的状态和信息
        data = {'code': 1000, }
        try:
            username = request._request.POST.get('username')
            password = request._request.POST.get('password')
            user = models.User.objects.filter(username=username, password=password).first()
            if not user:
                data['code'] = 1001
                data['error'] = '用户名或密码错误'
                return JsonResponse(data)
            token = get_token(username)
            models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
            data['token'] = token
            data['msg'] = '登录成功'
            return JsonResponse(data)
        except Exception as e:
            data['code'] = 1002
            data['error'] = '请求出错'
            return JsonResponse(data)
View Code

 

UserAuth

from app01 import models
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication

class UserAuth(BaseAuthentication):
    """
    用户认证是否登录
    """

    def authenticate(self, request):
        try:
            token = request._request.GET.get('token')
            user_token = models.UserToken.objects.filter(token=token).first()
            if not user_token:
                raise exceptions.AuthenticationFailed('用户未登录')
            return user_token.user, token
        except:
            raise exceptions.AuthenticationFailed('请求出错')
View Code

 

局部配置

# 在视图函数中配置上,可配一个或多个
authentication_classes = [UserAuth]

 

全局配置

REST_FRAMEWORK={
        'DEFAULT_AUTHENTICATION_CLASSES':['app01.utils.auth.UserAuth'],
         # 认证不通过或认证类通过认证但无返回值时,设置的用户和token 默认为AnonymousUser和None.
         UNAUTHENTICATED_USER:"匿名用户",
         UNAUTHENTICATED_TOKEN:None             
}

 

权限

view

from django.http import JsonResponse
from rest_framework.views import APIView
from app01.utils.permission import SVIPPermission
from app01 import models

class OrderView(APIView):
    # authentication_classes = [UserAuth,]
    permission_classes = [SVIPPermission, ]
    throttle_classes = [IPThrottle, ]

    def get(self, request, *args, **kwargs):
        self.dispatch()
        ret = {'code': 1000, 'msg': None, 'data': None}
        try:
            ret['data'] = '订单信息'
            ret['msg'] = '已登录'
        except:
            ret['code'] = 1001
            ret['msg'] = '未登录'

        return JsonResponse(ret)
View Code

 

permission

from rest_framework.permissions import BasePermission


class SVIPPermission(BasePermission):
    message = '无权限访问'

    def has_permission(self, request, view):

        if request.user.level == 3:
            return True
        else:
            return False
View Code

节流

基于用户IP限制访问频率

 urls.py
 views.py

b. 基于用户IP显示访问频率(利于Django缓存)

 settings.py
 urls.py
 views.py

c. view中限制请求频率

 settings.py
 urls.py
 views.py

d. 匿名时用IP限制+登录时用Token限制

 settings.py
 urls.py
 views.py

e. 全局使用

 settings

 

posted @ 2019-03-24 10:04  小夏02  阅读(76)  评论(0)    收藏  举报