• rest_framework 认证与权限


    一  认证

    1.1先写个类(认证组件)

    from app01 import models
    from rest_framework import exceptions
    from rest_framework.authentication import BaseAuthentication
    
    
    # 用drf的认证,写一个类,可以继承BaseAuthentication,也可以不用
    # class LoginAuth(BaseAuthentication):
    
    class LoginAuth():
        # 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象
        def authenticate(self, request):
            # 从request对象中取出token(也可以从其它地方取)
            token = request.query_params.get('token')
            # 去数据库过滤,查询
            ret = models.UserToken.objects.filter(token=token)
            if ret:
                # 能查到,说明认证通过,返回空
                # ret.user就是当前登录用户对象,一旦retrun了,后面的认证类都不执行了
                return ret.user,ret
            # 如果查不到,抛异常
            raise exceptions.APIException('您认证失败')

    1.2views

    def get_token(name):
        # 生成一个md5对象
        md5 = hashlib.md5()
        # 往里添加值,必须是bytes格式
        # time.time()生成时间戳类型,转成字符串,再encode转成bytes格式
        md5.update(str(time.time()).encode('utf-8'))
        md5.update(name.encode('utf-8'))
        return md5.hexdigest()
    
    
    # 登录
    class Login(APIView):
        authentication_classes = []
        def post(self, request, *args, **kwargs):
            response = {'status': 100, 'msg': '登录成功'}
            name = request.data.get('name')
            pwd = request.data.get('pwd')
            try:
                user = models.UserInfo.objects.get(name=name, pwd=pwd)
                # 校验通过,登录成功,生成一个随机字符串(身份标识)token
                token = get_token(name)
                # 保存到数据库
                # update_or_create更新或者创建
                models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
                response['token'] = token
            except ObjectDoesNotExist as e:
                response['status'] = 101
                response['msg'] = '用户名或密码错误'
            except Exception as e:
                response['status'] = 102
                # response['msg']='未知错误'
                response['msg'] = str(e)
            return JsonResponse(response, safe=False)
    class Books(APIView):
        # 列表中,类名不能加括号
        # authentication_classes = [LoginAuth, ]
    
        def get(self, request, *args, **kwargs):
            # 只要通过认证,就能取到当前登录用户对象
            print(request.user)
            response = {'status': 100, 'msg': '查询成功'}
            ret = models.Book.objects.all()
            book_ser = MySerializer.BookSerializer(ret, many=True)
            response['data'] = book_ser.data
            return JsonResponse(response, safe=False)

    1.3局部配置,全局配置,局部禁用

    1.3.1局部配置

    class Books(APIView):
        # 列表中,类名不能加括号
        # 局部配置,就是在需要认证功能的视图函数下加
        authentication_classes = [LoginAuth, ]
       

    1.3.2全局配置

    # 在settings中配置   
    REST_FRAMEWORK={
        'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.LoginAuth',],   #认证
        'DEFAULT_PERMISSION_CLASSES':['app01.MyAuth.Permission',]   #权限
    }

    1.3.3局部禁用

    class Books(APIView):
        # 列表中,类名不能加括号
        # 局部禁用,就是在需要认证功能的视图函数下的authentication_classes的列表置空
        authentication_classes = [ ]

    1.4认证的顺序

    认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类

    二  权限

    2.1写一个类(权限组件)

    class UserPermission(BasePermission):
        # message是出错显示的中文
        message='您没有权限查看'
        def has_permission(self, request, view):
            user_type = request.user.user_type
            # 取出用户类型对应的文字
            # 固定用法:get_字段名字_display()
            user_type_name = request.user.get_user_type_display()
            print(user_type_name)
            if user_type == 2:
                return True
            else:
                return False

    2.2权限的简单使用(views)

    # 需求,只能超级用户来查看作者详情,其他人不能看
    from app01.MyAuth import UserPermission
    class Authors(APIView):
        # permission_classes=[UserPermission,]
        # 局部禁用:
        permission_classes = []
        def get(self, request, *args, **kwargs):
    
    
            response = {'status': 100, 'msg': '查询成功'}
            ret = models.Author.objects.all()
            ser = MySerializer.AuthorSerializer(ret, many=True)
            response['data'] = ser.data
            return JsonResponse(response, safe=False)

     2.3局部配置,全局配置,局部禁用

    • 与认证用法相同

    2.4权限使用顺序

    权限类使用顺序:先用视图类中的权限类,再用settings里配置的权限类,最后用默认的权限类  

    三  不用再数据库中查询token的认证

    不在数据库中存token验证思路:

    在查看网站信息的时候要登录的,在登录的时候后台在拿到token,token是由加密算法函数中传入查询对象的id(或其他信息)产生的随机字符串.查看信息时,拿着这个与id(或其他信息)与随机字符串拼接的密文,在后台通过切分密文到查询对象的id(或其他信息),然后通过同样的算法得到随机字符串,比对他们是否相等

  • 相关阅读:
    WPF概述(硬件加速及分辨率无关性)
    创建自己的Code Snippet(代码模板)
    [LeetCode]46. Restore IP Addresses复原IP地址
    [LeetCode]45. Reverse Words in a String按单词翻转字符串
    [LeetCode]44. Implement strStr()实现strStr()函数
    [LeetCode]43. Integer to Roman整数转罗马数字
    [LeetCode]42. Roman to Integer罗马数字转整数
    [LeetCode]41. String to Integer(atoi)字符串转整数
    [LeetCode]40. Valid Palinadrome有效回文串
    [LeetCode]39. Longest Valid Parentheses最长有效括号对
  • 原文地址:https://www.cnblogs.com/zhaijihai/p/10115801.html
Copyright © 2020-2023  润新知