zoukankan      html  css  js  c++  java
  • rest framework 的权限管理

    下面是对单个的视图进行的设置的:

    请求的时候用postman然后发送信息

    我们下面所有的举例都是在用户对Comment这个表的操作

    首先先生成一个类似于cookie的字符串 发送给前端浏览器 然后下次它再访问带着这个认证字符串

    登陆视图

    #登陆视图
    
    class LoginView(APIView):
        def post(self,request):
            ret = {"status":0}
            print(request.data)
    
            username = request.data.get("username")
            password = request.data.get('password')
    
            user_obj = models.UserInfo.objects.filter(username = username,password = password).first()  # 校验看传递进来的是否对的
            print(11111)
    
            if user_obj:
                print(2222222)
                #校验成功 加密并且写入 Token中它的
                token = get_token_code(username)
                models.Token.objects.update_or_create(defaults={'token':token},user = user_obj)  # 有就更新 没有就创建
                ret['token'] = token  #加密的内容存起来
            else:
                ret['status'] = 1
                ret['error'] = "用户名或密码错误"
    
            return Response(ret)

    生成请求的token字符串:

    #生成Token函数
    def get_token_code(username):
        '''
        根据用户名和时间戳生成用户登陆成功过的随机字符串
        :param username:   字符串格式用户名
        :return:  字符串格式Token
        '''
    
        import time
        import hashlib
        timestamp = str(time.time())
        m = hashlib.md5(bytes(username,encoding="utf8"))
        m.update(bytes(timestamp,encoding="utf8"))
        return m.hexdigest()

    认证:     BaseAuthentication

    from rest_framework.authentication import  BaseAuthentication # 认证模块

    抛错模块:

    from rest_framework.exceptions import AuthenticationFailed   # 模块报错 返回信息

    我们可以根据这个来设置 登陆人的信息  只有登陆成功后才能进行提交post之类的操作 

    这个时候就用到了我们的权限设置

    我们写一个文件来存放登陆的信息设置:

    from rest_framework.authentication import  BaseAuthentication # 认证模块
    
    from first import models
    
    from rest_framework.exceptions import AuthenticationFailed   # 模块报错 返回信息
    import logging
    logger = logging.getLogger(__name__)
    class MyAuth(BaseAuthentication):
    
        def authenticate(self, request):
            print(request.method)
            if request.method in ["POST","PUT","DELETE"]:
                token = request.data.get("token")  #获取你登陆的信息
                token_obj = models.Token.objects.filter(token = token).first()  #去数据库中阿奎那有没有这个数据
                if token_obj:
                    return token_obj.user,token
                else:
                    raise AuthenticationFailed('无效的token')
            else:
                return None,None

    views:

    就是把你的认证设置导入进来 然后再用到post get操作的总操作的集合模块对操作设置

    from first.utils.auth  import MyAuth  #导入你的 认证信息设置
    
    class CommentViewSet(ModelViewSet):
        queryset = models.Comment.objects.all()
        serializer_class = first_serializers.Commentserializer  #这个是你的对Comment的定义设置的
    
        authentication_classes =  [MyAuth]   # 让你设置的认证生效

    视图级别认证

    class CommentViewSet(ModelViewSet):
    
        queryset = models.Comment.objects.all()
        serializer_class = app01_serializers.CommentSerializer
        authentication_classes = [MyAuth, ]

    全局级别认证

    # 在settings.py中配置
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ]
    }

    权限管理:BasePermission  

    from rest_framework.permissions import  BasePermission   #导入权限设置的模块

    也是设置一个权限管理的模块:

    from rest_framework.permissions import  BasePermission   #导入权限设置的模块
    
    
    class MyPermission(BaseException):
        message = '快滚,没有权限!'
    
        def has_permission(self,request,view):
            '''
            判断该用户有没有权限
            如果有就返回True
            如果没有就返回False
            '''
            print('我要进行自定义设置了')
            return True
    
        def has_object_permission(self,request,view,obj):   # 重写父类的方法 名字必须这样
    
            '''
            obj是你的当前文章的作者对象
            判断当前的评论用户作者是不是你当前的用户
            只有评论的作者才能删除自己的评论
            '''
            if request.method in ['PUT',"DELETE"]:
                if obj.user == request.user:
                    # 当前要删除的评论的作者就是当前登陆的用户
                    return True
                else:
                    return False
            else:
                return True

    views:

    from first.utils.auth  import MyAuth  #导入你的 认证信息设置
    from first.utils.permission import MyPermission  #导入权限管理的模块
    
    class CommentViewSet(ModelViewSet):
        
        queryset = models.Comment.objects.all()
        serializer_class = first_serializers.Commentserializer  #这个是你的对Comment的定义设置的
    
        authentication_classes =  [MyAuth,]
     
        permission_classes = [MyPermission,]  # 把你权限管理的设置导入进来

    这个时候你就要给你的url设置了 就像之前解除的  继承全局的然后并不需要设置很多url  设置一个就可以

    ursl:

    from rest_framework.routers import DefaultRouter
    
    router = DefaultRouter()
    router.register(r'comment', views.CommentViewSet)    #这个就是设置你的输入并且查找的视图
    urlpatterns += router.urls

    限制:

    from rest_framework.throttling import  SimpleRateThrottle

    定义一个访问次数限制:

    自定以的限制:

    class VisitThorttle(SimpleRateThrottle):
        scope = "ooo"  #这个名字随便起 是你设置全局的时候的给对应的
        def get_cache_key(self, request, view):
            return self.get_ident(request)  # 求当前访问的IP

    其实上面是执行了这个流程:

    '''
    自定义访问限制类
    '''
    
    
    from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
    
    from rest_framework.throttling import  SimpleRateThrottle
    
    import time
    
    D = {}
    
    class MyThorttle(BaseThrottle):
        def allow_request(self, request, view):
            '''
            返回True就放行 返回False 表示被限制了
    
            '''
            # 获取当前的ip
            ip = request.META.get("REMOTE_ADDR") # 获取请求的IP
            print('这是自定义希纳是类的allow_request')
            print(ip)
    
            #获取当前时间
            now = time.time()
            #判断当前ip是否有访问记录
            if ip in D:
                D[ip] = []  #初始化一个空的访问历史列表
            #高端
            history = D[ip]
            while history and now -history[-1] > 30:  #有ip并且当前时间减去储存的最后一个时间
                history.pop()
            if len(history) >= 3:
                return False
            else:
        # 把这一次的访问时间加到访问历史列表的第一位
                D[ip].insert(0,now)
                return True
    
    
    class VisitThorttle(SimpleRateThrottle):
        scope = "ooo"  #这个名字随便起
        def get_cache_key(self, request, view):
            return self.get_ident(request)  # 求当前访问的IP
    真正流程

    views:

    from first.utils.throttle import VisitThorttle  # 导入自定义访问限制
    
    class CommentViewSet(ModelViewSet):
    
        queryset = models.Comment.objects.all()
        serializer_class = first_serializers.Commentserializer  #这个是你的对Comment的定义设置的
       throttle_classes = [VisitThorttle,]   #把自定义的访问限制类

    全局设置   全局的请求设置是你只要进去就会触发  而我们在views中的设置  只是有针对的对一些视图进行设置

    全局设置:

    在settings设置;

    # rest framework相关的配置项
    REST_FRAMEWORK = {
         关于认证的全局配置
         'DEFAULT_AUTHENTICATION_CLASSES': ['app01.utils.auth.MyAuth', ],
         'DEFAULT_PERMISSION_CLASSES': ['app01.utils.permission.MyPermission'],
         #"DEFAULT_THROTTLE_CLASSES": ["app01.utils.throttle.MyThrottle", ],
        "DEFAULT_THROTTLE_RATES": {  # 这个和上面的都可以设置  
                "ooo": "5/m",    # ooo对应你后自定以的设置的scope
                "xxx": '10/m'
            }
    }

     

  • 相关阅读:
    NAT基本原理及应用
    端口转发和端口映射的区别
    Xshell不能连接Kali系统SSH的解决
    PowerSploit
    powertool
    Windows/Linux 下反弹shell
    Apache Shiro 反序列化漏洞复现(CVE-2016-4437)
    渗透测试神器Cobalt Strike使用教程
    Notepad++ 小技巧
    Linux:Day44(上)
  • 原文地址:https://www.cnblogs.com/zhaoyunlong/p/9416569.html
Copyright © 2011-2022 走看看