drf 自定义User表,签发token 自定义认证类 simpleui的使用

2022/5/22 23:03:10

本文主要是介绍drf 自定义User表,签发token 自定义认证类 simpleui的使用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

内容详细

1 自定义User表,签发token

        # 如果项目中的User表使用auth的user表,使用快速签发token即可
        # 如果自定义User表,签发token,需要手动签发---》自己写

1.1 普通写法

        from rest_framework.views import APIView
        # class UserView(APIView):
        # 自动生成路由,
        from rest_framework.viewsets import ViewSetMixin
        from rest_framework.decorators import action
        from rest_framework.generics import GenericAPIView
        from .models import UserInfo
        from .serializer import UserInfoSerializer
        from rest_framework.response import Response
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


        # /user/login/--->post请求
        # class UserView(ViewSetMixin, APIView):
        #     @action(methods=['POST'], detail=False)
        #     def login(self, request):
        #         res_dic = {'code': 100, 'msg': '成功'}
        #         username = request.data.get('username')
        #         password = request.data.get('password')
        #         user = UserInfo.objects.filter(username=username, password=password).first()
        #         if user:  # 登陆成功
        #             # 签发token?如何签发?--》去jwt源码中扣
        #             payload = jwt_payload_handler(user)  # 得到荷载--》字典
        #             print(payload)
        #             token = jwt_encode_handler(payload)  # 通过荷载得到token串
        #             res_dic['token'] = token
        #             res_dic['username'] = user.username
        #             return Response(res_dic)
        #         else:
        #             res_dic['code'] = 101
        #             res_dic['msg'] = '用户名或密码错误'
        #             return Response(res_dic)

1.2 逻辑写在序列化类中

        # 换种写法,写上面的登录,所有校验规则,写在序列化类中---》这种用的多
        class UserView(ViewSetMixin, APIView):
            @action(methods=['POST'], detail=False)
            def login(self, request):
                res_dic = {'code': 100, 'msg': '成功'}
                ser = UserInfoSerializer(data=request.data,context={'request':request})
                if ser.is_valid():  # 这句话会走:字段自己的校验规则,局部钩子,全局钩子
                    token = ser.context.get('token')
                    username = ser.context.get('username')
                    # token = ser.token
                    # username = ser.username
                    res_dic['token'] = token
                    res_dic['username'] = username
                else:
                    res_dic['code'] = 101
                    res_dic['msg'] = ser.errors
                return Response(res_dic)

        class UserInfoSerializer(serializers.ModelSerializer):
            class Meta:
                model = UserInfo
                fields = ['username', 'password']  # 根据表模型中写的,字段自己有校验规则

            def validate(self, attrs):
                # 打印请求方式?
                print(self.context.get('request').method)
                # 签发token逻辑,签发生成token,放到ser.context字典中
                username = attrs.get('username')
                password = attrs.get('password')
                user = UserInfo.objects.filter(username=username, password=password).first()
                if user:  # 登陆成功
                    payload = jwt_payload_handler(user)  # 得到荷载--》字典
                    token = jwt_encode_handler(payload)  # 通过荷载得到token串
                    # serializer和视图类沟通的桥梁
                    self.context['token'] = token
                    self.context['username'] = user.username
                    # self.token=token
                    # self.username=username
                else:
                    raise ValidationError('用户名或密码错误')
                return attrs

2 自定义认证类

        from rest_framework.authentication import BaseAuthentication
        from rest_framework_jwt.settings import api_settings
        from rest_framework.exceptions import AuthenticationFailed
        import jwt
        # from django.utils.translation import ugettext as _
        from .models import UserInfo
        jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
        class JWTAuthentication(BaseAuthentication):
            def authenticate(self, request):
                # 第一步:取出传入的token--》从哪去?--》咱们定的:请求地址?请求头?
                # token=request.query_params.get('token')# 请求地址?
                # http请求头中的数据,在META中,统一变成  HTTP_请求头的key大写
                jwt_value=request.META.get('HTTP_TOKEN')
                if jwt_value:
                    # 验证token:是否过期,是否被篡改--》去源码扣
                    try:
                        payload = jwt_decode_handler(jwt_value)
                    except jwt.ExpiredSignature:
                        msg = '签名过期'
                        raise AuthenticationFailed(msg)
                    except jwt.DecodeError:
                        msg = '签名被篡改'
                        raise AuthenticationFailed(msg)
                    except jwt.InvalidTokenError:
                        raise AuthenticationFailed('未知错误')

                    # 通过payload获得当前登录用户
                    user = UserInfo.objects.filter(pk=payload['user_id']).first()

                    return (user, jwt_value)
                else:
                    raise AuthenticationFailed('您没有携带token')

3 simpleui的使用

        # django-admin混合开发--》后台管理---》美化--》simpleui

        # 使用步骤:
            -安装:pip3 install django-simpleui
          -注册app
            INSTALLED_APPS = [
              'simpleui',
            ]
          -定制左侧菜单
            SIMPLEUI_CONFIG = {
            'system_keep': False,
            'menu_display': ['监控大屏','应用1', '权限认证', '测试', '动态菜单测试'],  # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
            'dynamic': True,  # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
            'menus': [
                {
                    'name': '监控大屏',
                    'icon': 'fas fa-code',
                    'url': '/index/'
                },
                {
                    'app': 'app01',
                    'name': '应用1',
                    'icon': 'fas fa-user-shield',
                    'models': [
                        {
                            'name': '图书',
                            'icon': 'fa fa-user',
                            'url': 'app01/book/'
                        },
                        {
                            'name': '用户',
                            'icon': 'fa fa-user',
                            'url': 'app01/userinfo/'
                        }
                    ]
                },
                {
                    'app': 'auth',
                    'name': '权限认证',
                    'icon': 'fas fa-user-shield',
                    'models': [
                        {
                            'name': '用户',
                            'icon': 'fa fa-user',
                            'url': 'auth/user/'
                        },
                        {
                            'name': '用户组',
                            'icon': 'fa fa-user',
                            'url': 'auth/group/'
                        }
                    ]
                },
                {
                    # 自2021.02.01+ 支持多级菜单,models 为子菜单名
                    'name': '测试',
                    'icon': 'fa fa-file',
                    # 二级菜单
                    'models': [{
                        'name': 'Baidu',
                        'icon': 'far fa-surprise',
                        # 第三级菜单 ,
                        'models': [
                            {
                                'name': '爱奇艺',
                                'url': 'https://www.iqiyi.com/dianshiju/'
                                # 第四级就不支持了,element只支持了3级
                            }, {
                                'name': '百度问答',
                                'icon': 'far fa-surprise',
                                'url': 'https://zhidao.baidu.com/'
                            }
                        ]
                    }, {
                        'name': '内网穿透',
                        'url': 'https://www.wezoz.com',
                        'icon': 'fab fa-github'
                    }]
                },
                {
                    'name': '动态菜单测试',
                    'icon': 'fa fa-desktop',
                    'models': [{
                        'name': time.time(),
                        'url': 'http://baidu.com',
                        'icon': 'far fa-surprise'
                    }]
                }
            ]
        }
          -自带权限
          -自定义左侧菜单的页面显示
            -通过混合开发,编写路径,配置到上面即可
          -更多操作见官方


这篇关于drf 自定义User表,签发token 自定义认证类 simpleui的使用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程