django --权限认证与自定义响应结果(drf异常类)

settings配置

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    # 配置默认页面大小
    'PAGE_SIZE': 10,
    # 配置默认的分页类
    'DEFAULT_PAGINATION_CLASS': 'backstage.helps.MyPageNumberPagination',

    # 配置异常处理器
    # 'EXCEPTION_HANDLER': 'api.exceptions.exception_handler',
    'EXCEPTION_HANDLER': 'backstage.utils.exception_handler',  # 替换为自定义的路径

    # 配置默认解析器
    # 'DEFAULT_PARSER_CLASSES': (
    # 'rest_framework.parsers.JSONParser',
    # 'rest_framework.parsers.FormParser',
    # 'rest_framework.parsers.MultiPartParser',
    # ),

    # 配置默认限流类
    # 'DEFAULT_THROTTLE_CLASSES': (),

    # 配置默认授权类
    # 'DEFAULT_PERMISSION_CLASSES': (
    # 'rest_framework.permissions.IsAuthenticated',
    # ),

}

重写异常

import datetime

import jwt
from jwt import InvalidTokenError
from redis import RedisError
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from django_filters import filterset
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed, APIException

from backstage.models import Data, BackstageUser
from express import settings

import threading

from express.settings import SECRET_KEY

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseError


class BaseAuthException(Exception):
    '''自定义权限异常'''

    def __init__(self, msg):
        self.msg = msg
        super().__init__(self, msg)

    def __str__(self):
        return str(self.msg)

    def __call__(self, *args, **kwargs):
        return str(self.msg)


def exception_handler(exc, context):
    """
    自定义异常处理
    :param exc: 别的地方抛的异常就会传给exc
    :param context: 字典形式。抛出异常的上下文(即抛出异常的出处;即抛出异常的视图)
    :return: Response响应对象
    """
    # 调用drf框架原生的异常处理方法,把异常和异常出处交给他处理,如果是序列化器异常就直接处理,处理之后就直接返回
    response = drf_exception_handler(exc, context)
    print('222', response)
    print('111', exc)
    # 如果响应为空表示不是序列化器异常,补充数据库异常 和 认证异常
    if response is None:
        if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
            # 数据库异常
            response = Response({'msg': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

        elif isinstance(exc, BaseAuthException):
            response = Response({'code': 500, 'msg': '无效的令牌或令牌已过期,请重新登录'})

        # --- 未捕获则直接报错

    return response


class LoginRequiredAuthentication(BaseAuthentication):
    """登录认证"""

    # 如果用户身份验证成功需要返回一个二元组(user, token)
    def authenticate(self, request):
        token = request.META.get('HTTP_TOKEN')
        if token:
            try:
                print('进入权限认证')
                payload = jwt.decode(token, SECRET_KEY)
                user = BackstageUser()
                print(f'解析参数-->{payload}')
                user.userid = payload['userid']
                user.is_authenticated = True
                return user, token
            except InvalidTokenError:
                raise BaseAuthException('请提供用户身份令牌')
        raise AuthenticationFailed('请提供用户身份令牌')


class SingletonType(type):
    '''多线程(元类单例)'''
    _instance_lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with SingletonType._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = super(SingletonType, cls).__call__(*args, **kwargs)
        return cls._instance

views中

class UserView(BaseModelViewSet):
    '''用户信息crud'''
    queryset = User.objects.all().order_by('-user_id')
    serializer_class = UserSimpleSerializer
    authentication_classes = (LoginRequiredAuthentication,)
    ....
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

像风一样的男人@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值