django-drf 认证 权限 频率

本文介绍了如何在DjangoRestFramework中自定义认证类,如AuthLogin,以及如何使用自定义权限类(如Authority)进行权限控制,包括choices的使用和频率限制功能。还讨论了全局和局部配置选项。
摘要由CSDN通过智能技术生成

自定义认证类

# 认证类文件
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from app01 import models

# token 的两种方式  第一种是放在get请求地址栏中  一种是放在请求头中 在Meta中取
# 如果不继承 BaseAuthentication 则是还要重写 authenticate_header 方法
# 但是 authenticate 方法是必写的
class AuthLogin(BaseAuthentication):

    def authenticate(self,request):
        user_token = request.GET.get('token') or request.META.get('HTTP_TOKEN')
        token = models.User_Token.objects.filter(token=user_token).first()

        if token:
            # 通过token拿到当前登录用户
            user = token.user

            # 必须返回用户和token串 不然后续视图类中给前端的时候拿不到了
            return user,token
        else:
            raise AuthenticationFailed('您没有登录')

    # #  如果不继承 BaseAuthentication 则是需要重写这个方法
    # def authenticate_header(self,request):
    #     pass



# 视图类
from rest_framework.generics import GenericAPIView
from app01.serializer import BookSerializer

class LoginView(APIView):

    def post(self,request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = models.Userinfo.objects.filter(username=username, password=password).first()

        if user:
            import uuid
            token = uuid.uuid4()
            # user=user 先查询有没有这个用户信息 有就更新 没有defaults={'token':token} 修改
            models.User_Token.objects.update_or_create(defaults={'token': token}, user_id=user.pk)

            return Response({'code': 200, 'msg': '登录成功', 'token': token})
        return Response({'code': 201, 'msg': '用户或密码错误'})


class Bookview(GenericAPIView):
	# 局部配置只需要在这里 写上即可 只有携带token才能访问这个接口
    authentication_classes = [AuthLogin]

    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def get(self,request):
        object_list = self.get_queryset()  # 一定要加上括号
        # 序列化的参数和 APIView 一样的
        ser = self.get_serializer(instance=object_list, many=True)
        return Response({'code': 100, 'msg': '查询所有成功', 'result': ser.data})


"""
1 全局使用(所有接口,都需要登录才能访问)
	-在配置文件中
        REST_FRAMEWORK = {
       [ "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ]
        }
2 局部使用
	-在想局部使用的视图类上
	authentication_classes = [MyAuthen.LoginAuth,]
3 局部禁用
	-在想禁用的视图类上
    authentication_classes = []
   
"""

自定义权限类

from app01 import models
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.auth_class import AuthLogin
from rest_framework.generics import GenericAPIView
from app01.serializer import BookSerializer


class LoginView(APIView):

    def post(self,request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = models.Userinfo.objects.filter(username=username, password=password).first()

        if user:
            import uuid
            token = uuid.uuid4()
            # user=user 先查询有没有这个用户信息 有就更新 没有defaults={'token':token} 修改
            models.User_Token.objects.update_or_create(defaults={'token': token}, user_id=user.pk)

            return Response({'code': 200, 'msg': '登录成功', 'token': token})
        return Response({'code': 201, 'msg': '用户或密码错误'})

from app01 import auth_class
class Bookview(GenericAPIView):
    
    # 认证类写在前面  只有登录之后带着token过来才能访问这个接口
    authentication_classes = [AuthLogin]
    # 权限类
    permission_classes = [auth_class.Authority]

    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def get(self,request):
        object_list = self.get_queryset() 
  
        ser = self.get_serializer(instance=object_list, many=True)
        return Response({'code': 100, 'msg': '查询所有成功', 'result': ser.data})
from rest_framework.permissions import BasePermission

class Authority(BasePermission):

    def has_permission(self,request, view):

        try:
            user_admin = request.user.user_admin
            if user_admin == 2:
                return True
            else:
            	 # 通过 get_字段名——display() 取出 chionse对应的字符
                self.message = '你是 %s,没有权限访问' % request.user.get_user_admin_display()
                return False
        except Exception:

            # 这个是返回给前端的提示 如果不重写 使用默认的
            self.message = '你没有登录,没有权限访问'
            self.code = {'code':404}
            return False
            
# 全局配置和局部配置
REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.MyAuthen.LoginAuth", ]
        "DEFAULT_PERMISSION_CLASSES": ["app01.MyAuthen.SuperPermission", ]
        }

局部配置 
     -局部禁用
 class Bookview(GenericAPIView):    
    permission_classes = []
    pass0

choices的使用

get_字段名_display()的方法,该方法获得choice字段对应的数据

 class Userinfo(models.Model):
     
        choices_admin = ((1, '普通用户'), (2, '管理员用户'), (3, '二笔用户'))
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        user_admin = models.IntegerField(default=1, choices=choices_admin)
        
        
from rest_framework import serializers
class Usernameserializer(serializers.ModelSerializer):
    
    choices_user = serializers.CharField(max_length=32,source='get_choices_admin_display()')
    
    class Meta:
        model = models.Userinfo
        fields = ['username', 'password', 'user_admin','choices_user']

频率限制

# 视图类 
class Bookview(GenericAPIView):
    # 认证类写在前面  只有登录之后带着token过来才能访问这个接口
    authentication_classes = [AuthLogin]
    # # 权限类
    permission_classes = [auth_class.Authority]
    # 频率限制
    throttle_classes = [auth_class.MySimpleThrottle]

    queryset = models.Book.objects.all()
    serializer_class = BookSerializer

    def get(self,request):
        object_list = self.get_queryset()
        ser = self.get_serializer(instance=object_list, many=True)
        return Response({'code': 100, 'msg': '查询所有成功', 'result': ser.data})


# 重写频率类
from rest_framework.throttling import SimpleRateThrottle

class MySimpleThrottle(SimpleRateThrottle):
    scope = 'time'

    # get_cache_key 这个方法必须重写
    def get_cache_key(self, request, view):

        # ip = request.META.get('REMOTE_ADDR')
        # return ip # 两种都是一样的

        # 以ip限制 内部的
        return self.get_ident(request)

# setting.py 
REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_RATES' : {
                'time':'10/m'# key跟scope对应,value是一个时间 m是一分钟 d是一个月 h是一小时
            }
        }
# 局部配置 就是
throttle_classes = []
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值