• 认证组件,权限组件,频率组件,控制版本


    认证组件 
    1 写一个认证类
    from rest_framework.authentication import BaseAuthentication
    class MyAuth(BaseAuthentication):
    def authenticate(self,request):
    # request 是封装后的
    token = request.query_params.get('token')
    ret = models.UserToken.objects.filter(token=token).first()
    if ret:
    # 认证通过
    return
    else:
    raise AuthenticationFailed('认证失败')
    #可以不写了
    def authenticate_header(self,ss):
    pass
    2 局部使用
    authentication_classes=[MyAuth,MyAuth2]
    3 全局使用
    查找顺序:自定义的APIView里找---》项目settings里找---》内置默认的
    REST_FRAMEWORK={
    'DEFAULT_AUTHENTICATION_CLASSES':['utils.common.MyAuth',]
    
    }
    
    
    权限组件 
    1 写一个类
    from rest_framework.permissions import BasePermission
    class MyPermission(BasePermission):
    message = '不是超级用户,查看不了'
    def has_permission(self,request,view):
    token=request.query_params.get('token')
    ret=models.UserToken.objects.filter(token=token).first()
    if ret.user.type==2:
    # 超级用户可以访问
    return True
    else:
    return False
    2 局部使用:
    permission_classes=[MyPermission,]
    3 全局使用:
    REST_FRAMEWORK={
    'DEFAULT_PERMISSION_CLASSES':['utils.common.MyPermission',]
    }
    
    频率组件 
    1 写一个类:
    from rest_framework.throttling import SimpleRateThrottle
    class VisitThrottle(SimpleRateThrottle):
    scope = 'xxx'
    def get_cache_key(self, request, view):
    return self.get_ident(request)
    2 在setting里配置:
    'DEFAULT_THROTTLE_RATES':{
    'xxx':'5/h',
    }
    3 局部使用
    throttle_classes=[VisitThrottle,]
    4 全局使用
    REST_FRAMEWORK={
    'DEFAULT_THROTTLE_CLASSES':['utils.common.VisitThrottle',]
    }

    认证,想局部取消(禁用)比如login登录的时候就需要禁用掉认证
    authentication_classes=[]

    认证组件 不存数据库的token验证

    视图层:

    def get_token(id,salt='123'):
        import hashlib
        md=hashlib.md5()
        md.update(bytes(str(id),encoding='utf-8'))
        md.update(bytes(salt,encoding='utf-8'))
    
        return md.hexdigest()+'|'+str(id)
    
    def check_token(token,salt='123'):
        ll=token.split('|')
        import hashlib
        md=hashlib.md5()
        md.update(bytes(ll[-1],encoding='utf-8'))
        md.update(bytes(salt,encoding='utf-8'))
        if ll[0]==md.hexdigest():
            return True
        else:
            return False
    
    class TokenAuth():
        def authenticate(self, request):
            token = request.GET.get('token')
            success=check_token(token)
            if success:
                return
            else:
                raise AuthenticationFailed('认证失败')
        def authenticate_header(self,request):
            pass
    class Login(APIView):
        def post(self,reuquest):
            back_msg={'status':1001,'msg':None}
            try:
                name=reuquest.data.get('name')
                pwd=reuquest.data.get('pwd')
                user=models.User.objects.filter(username=name,password=pwd).first()
                if user:
                    token=get_token(user.pk)
                    # models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
                    back_msg['status']='1000'
                    back_msg['msg']='登录成功'
                    back_msg['token']=token
                else:
                    back_msg['msg'] = '用户名或密码错误'
            except Exception as e:
                back_msg['msg']=str(e)
            return Response(back_msg)
    from rest_framework.authentication import BaseAuthentication
    class TokenAuth():
        def authenticate(self, request):
            token = request.GET.get('token')
            token_obj = models.UserToken.objects.filter(token=token).first()
            if token_obj:
                return
            else:
                raise AuthenticationFailed('认证失败')
        def authenticate_header(self,request):
            pass
    
    class Course(APIView):
        authentication_classes = [TokenAuth, ]
    
        def get(self, request):
            return HttpResponse('get')
    
        def post(self, request):
            return HttpResponse('post')
    View Code

    频率组件

    2 频率:
        django自带了频率控制类,比如是flask没有这种类的话需要自己写频率控制类
        为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次
        自定义的逻辑
    
        #(1)取出访问者ip
        # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
        # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
    
    视图层:    
    class MyThrottles():
        VISIT_RECORD = {}
        def __init__(self):
            self.history=None
        def allow_request(self,request, view):
            #(1)取出访问者ip
            # print(request.META)
            ip=request.META.get('REMOTE_ADDR')
            import time
            ctime=time.time()
            # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
            if ip not in self.VISIT_RECORD:
                self.VISIT_RECORD[ip]=[ctime,]
                return True
            self.history=self.VISIT_RECORD.get(ip)
            # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
            while self.history and ctime-self.history[-1]>60:
                self.history.pop()
            # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
            # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
            if len(self.history)<3:
                self.history.insert(0,ctime)
                return True
            else:
                return False
        def wait(self):
            import time
            ctime=time.time()
            return 60-(ctime-self.history[-1])
    
    
        2.1自定义: 
            1 定义一个类MyThrottles
                allow_request(频率限制的逻辑)
                wait(返回一个数字,给用户提示,还差多少秒)
            2 局部使用:throttle_classes=[MyThrottles,]
            3 全局使用:'DEFAULT_THROTTLE_CLASSES':['utils.common.MyThrottles',],
    
            
        2.2用内置的:(可以控制ip,和userid)    
        from rest_framework.throttling import SimpleRateThrottle
        class VisitThrottle(SimpleRateThrottle):
            scope = 'xxx'
            def get_cache_key(self, request, view):
                # 这里可以写按照用户或者ip来限制频率
                # ip=rquest.META.get('REMOTE_ADDR')
                pk = request.user.pk
                return pk
                # return self.get_ident(request)
                
            1 写一个类,继承SimpleRateThrottle
                属性:scope = 'xxx'
                重写方法:get_cache_key
                去setting里配置:'DEFAULT_THROTTLE_RATES':{
                                    # 'xxx':'5/m',
                                    'xxx':'5/m',
                                }        
            2 局部使用:throttle_classes=[MyThrottles,]
            3 全局使用:'DEFAULT_THROTTLE_CLASSES':['utils.common.MyThrottles',],
            
    
    错误信息的中文提示:        
    class Course(APIView):
        authentication_classes = [TokenAuth, ]
        permission_classes = [UserPermission, ]
        throttle_classes = [MyThrottles,]
    
        def get(self, request):
            return HttpResponse('get')
    
        def post(self, request):
            return HttpResponse('post')
        def throttled(self, request, wait):
            from rest_framework.exceptions import Throttled
            class MyThrottled(Throttled):
                default_detail = '傻逼啊'
                extra_detail_singular = '还有 {wait} second.'
                extra_detail_plural = '出了 {wait} seconds.'
            raise MyThrottled(wait)
    View Code

    版本控制: 取不同url中的版本

        url:
        url(r'^testversion/', views.Test.as_view()),
        url(r'^(?P<version>[v1|v2|v3]+)/testversion/', views.Test2.as_view(),name='ttt'),
        
        视图:
        from django.shortcuts import render,HttpResponse
    
        # Create your views here.
    
        from rest_framework.views import APIView
    
        from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning
        class Test(APIView):
            versioning_class = QueryParameterVersioning
            def get(self,request,*args,**kwargs):
                print(request.version)
                return HttpResponse('ok')
    
        from django.urls import reverse
        class Test2(APIView):
            versioning_class = URLPathVersioning
            def get(self,request,*args,**kwargs):
                print(request.version)
                url=request.versioning_scheme.reverse(viewname='ttt',request=request)
                print(url)
                url2=reverse(viewname='ttt',kwargs={'version':'v1'})
                print(url2)
                return HttpResponse('ok')
    
        
        1 127.0.0.1/course/?version=v100000
            路由:
            url(r'^testversion/', views.Test.as_view()),
            视图层:
          用from rest_framework.versioning import QueryParameterVersioning
          class Test(APIView):
            versioning_class = QueryParameterVersioning
            def get(self,request,*args,**kwargs):
                print(request.version)
                return HttpResponse('ok')
          在视图类里:
            versioning_class=QueryParameterVersioning(**不再是列表)
          在setting里配置:
            REST_FRAMEWORK={
                'VERSION_PARAM':'version',
                'DEFAULT_VERSION':'v2',
                'ALLOWED_VERSIONS':['v1','v2']
            }
          取:
                视图类里:
                request.version
        
        127.0.0.1/v1/course/
        
              用from rest_framework.versioning import URLPathVersioning
              在视图类里:
                versioning_class=URLPathVersioning**不再是列表)
              在setting里配置:
                REST_FRAMEWORK={
                    'VERSION_PARAM':'version',
                    'DEFAULT_VERSION':'v2',
                    'ALLOWED_VERSIONS':['v1','v2']
                }
              取:
                视图类里:
                request.version
    
        3 反向解析(了解)
    View Code
  • 相关阅读:
    电脑开机小键盘灯不亮,应该怎么设置?
    关于SqlServer数据库日期函数
    SqlServer数据库几种字段类型对比
    如何查找计算机端口?
    实用的几个小命令
    SqlServer中创建Oracle连接服务器
    局域网内设置打印机
    SqlServer2008数据库自动备份设置
    文件内容替换BAT
    Dockerfile文件与常用指令详解(2) Marathon
  • 原文地址:https://www.cnblogs.com/xujinjin18/p/9833923.html
Copyright © 2020-2023  润新知