zoukankan      html  css  js  c++  java
  • 认证组件,权限组件,频率组件,控制版本

    认证组件 
    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
  • 相关阅读:
    进度条
    html5 表单新增事件
    html5 表单的新增type属性
    html5 表单的新增元素
    html5 语义化标签
    jq 手风琴案例
    codeforces 702D D. Road to Post Office(数学)
    codeforces 702C C. Cellular Network(水题)
    codeforces 702B B. Powers of Two(水题)
    codeforces 702A A. Maximum Increase(水题)
  • 原文地址:https://www.cnblogs.com/xujinjin18/p/9833923.html
Copyright © 2011-2022 走看看