DjangoRestFramework之认证组件,权限组件,频率组件

一 . 认证组件

我们现在知道的认证机制有cookie, session,session比较安全,session的信息是存在服务器上的,
如果用户量足够大的话,服务器的压力也就比较大,并且django的session存到了django_session表中,不是很好操作,现在生产中使用的一个叫做token机制的方式比较多.
可以使用这个机制把token存到用户信息里,当用户登录成功的时候放里面,等他来的时候就要带着这个来,而且们每次来的时候都更新token,防止被拦截.

  我们这里使用一下token,首先要建一个表,和user表一对一关系

  models.py

class User(models.Model):
    username = models.CharField(max_length=16)
    password = models.CharField(max_length=16)
    types = ((1, 'VIP'), (2, 'SVIP'), (3, 'SSVIP'))
    usertype = models.IntegerField(choices=types, default=1)

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

  URL

url(r'^login/$', views.LoginView.as_view()),  # 别忘了$符号结尾

  视图函数,每次登录后自动刷新token

import uuid

# 用户登录认证
class UserAuth(APIView):
    RET = {
        'code': None,
        'userinfo': None,
        'msg': None,
        'token': None
    }

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user_obj = models.User.objects.filter(username=username, password=password).first()
        if user_obj:
            random_str = uuid.uuid4()
            models.UserToken.objects.update_or_create(    # 有就更新,没有就创建
                user=user_obj,
                defaults={
                    'token': random_str,
                }
            )
            self.RET['code'] = 0  # 跟前端约定好,0表示成功
            self.RET['userinfo'] = username
            self.RET['msg'] = 'success'
            self.RET['token'] = random_str
        else:
            self.RET['code'] = -1
            self.RET['userinfo'] = username
            self.RET['msg'] = 'failure'
        return Response(self.RET)

  我们这里写一下DRF的认证组件

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

# drf提供认证失败的异常
class UserAuthToken(BaseAuthentication):

    # authenticate方法是固定的,并且必须写这个名字,是request新对象
    def authenticate(self, request):
        token = request.query_params.get('token')  # 类似于GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if token_obj:
            return token_obj.user, token   # 要么就返回两个值,要么就不返回
        else:
            return AuthenticationFailed('认证失败')  

  我们需要把这个认证组件 写到每一个url对应的视图函数中,加上认证,有token就可以访问,没有就拒绝 

class BookHandle(APIView):
    authentication_classes = [UserAuthToken, ]  #一进到这个函数就进行验证,变量名必须是这个,认证组件需要从所在文件中导入

    # 获取所有数据
    def get(self, request):
        book_obj_list = models.Book.objects.all()
        book_res = BookSerializer(book_obj_list, many=True)
        return Response(book_res.data)

  需要补两张成功与失败的对比图!!!

  全局视图组件(写在settings.py中)

  

二 . 权限组件

  权限组件

from rest_framework.permissions import BasePermission
class UserPermission(BasePermission):
    message = "SVIP才能访问!"  # 变量只能叫做message,权限不够的话返回message里面的数据

    def has_permission(self, request, view):  # view是用权限的视图函数
        if request.user.usertype == 3:   # user表中usertype的字段表示权限级别
            return True  # 通过权限,只能写True或False
        return False  # 没有通过

  视图函数

class BookHandle(APIView):
    permission_classes = [UserPer, ]  # 一进函数就验证,只有有权限的才能访问下面的数据
    # 获取所有数据
    def get(self, request):
        book_obj_list = models.Book.objects.all()
        book_res = BookSerializer(book_obj_list, many=True)
        return Response(book_res.data)

  全局视图权限(写在settings.py文件)

三 . 频率组件 

  内置的throttles类

from rest_framework.throttling import SimpleRateThrottle

class VisitThrottle(SimpleRateThrottle):

    scope="visit_rate"   # 限制访问次数用的
    def get_cache_key(self, request, view):   # 这个方法是固定的

        return self.get_ident(request)

  视图函数

class BookHandle(APIView):

    throttle_classes = [VisitThrottle, ]  # 添加访问频率,需要从该类所在位置引入

    # 获取所有数据
    def get(self, request):
        book_obj_list = models.Book.objects.all()
        book_res = BookSerializer(book_obj_list, many=True)
        return Response(book_res.data)

猜你喜欢

转载自www.cnblogs.com/attila/p/10805858.html
今日推荐