自定义djangorestframework-jwt返回

一:前言

Django rest framework给我们提供了很强大的功能,由于自带的token认证没有过期时间,而且token数据是保存在数据库的,这样一来无疑是加大了对数据库的压力,所以这是我们就可以使用jwt认证,jwt认证全称为json web token,他是通过加密解密进行认证的,用户的信息全部保存在加密体中(当然不会对敏感信息进行存放),由前端发送用户信息给后台,后台将信息加密返回给前端,然后前端保存在本地,每次请求的时候带着这个加密数据进行请求,这样一来,对于服务器来说就不会有很大的压力,当然这样做是会加大服务器的计算,但jwt认证的好处不只是这样,他还有利于对分布式部署的支持。

二:自定义返回信息

1: 成功信息自定义

当登录成功时jwt是默认只返回token信息的,当有些时候仅有一个token是不满足我们系统的,所以这时候我们需要对返回方法进行重写,代码如下:

def jwt_response_payload_handler(token, user=None, request=None, role=None):
    """
    自定义jwt返回数据
    """
    if user.first_name:
        name = user.first_name
    else:
        name = user.username
    return {
        "msg": "success",
        "status": 200,
        "data": [{
            'id': user.id,
            "role": role,
            'email': user.email,
            'name': name,
            'username': user.username,
            'token': token,
        }]
    }

方法完成后我们需要前往setting中对jwt进行配置,修改JWT_RESPONSE_PAYLOAD_HANDLER参数为刚刚方法:

# jwt载荷中的有效期设置
JWT_AUTH = {
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
    # token 有效期
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=3),
    'JWT_ALLOW_REFRESH': True,
    # 续期有效期(该设置可在24小时内带未失效的token 进行续期)
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24),
    # 自定义返回格式,需要手工创建
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'apps.users.views.jwt_response_payload_handler',
    # 'JWT_RESPONSE_PAYLOAD_ERROR_HANDLER': 'apps.users.views.jwt_response_payload_error_handler',
}

这样我们就完成了对成功登录返回信息的自定义修改,效果如下:
image.png

2: 失败信息自定义

登录失败信息自定义这里有两种方法,第一种就是修改django rest framework jwt的源码:
首先进入rest_framework_jwt的setting中在DEFAULTS中添加:

# 自定义ERROR返回
'JWT_RESPONSE_PAYLOAD_ERROR_HANDLER': 'rest_framework_jwt.utils.jwt_response_payload_error_handler',

然后在IMPORT_STRINGS中添加:

# 自定义ERROR返回
'JWT_RESPONSE_PAYLOAD_ERROR_HANDLER',

image.png
当修改好后,进入rest_framework_jwt的views里面添加:

jwt_response_payload_error_handler = api_settings.JWT_RESPONSE_PAYLOAD_ERROR_HANDLER

image.png
并修改post方法的失败返回值:
image.png
这样一来我们源码就修改好了,然后就可以像自定义成功返回值一样,自己编写方法然后去setting中进行配置就行了:
自定义失败返回方法:

def jwt_response_payload_error_handler(serializer, request=None):
    return {
        "msg": "用户名或者密码错误",
        "status": 400,
        "detail": serializer.errors
    }

setting配置:
image.png
当然这样直接修改源码会有一个问题,就是每次我们重新部署的时候都需要去修改源码,这样做的话会很麻烦,所以我们可以在工程目录下创建一个包,然后将修改好的源码放进去,这样一来的话我们就不必要每次都去修改jwt的源码,但是,想要使用包中修改的源码我们需要在setting中增加一个配置,这样需要找包就优先前往这个包里找源码了:
image.png
当然这是第一种修改方式,还有一种修改方式是自定义middleware,然后通过middleware对response进行修改,话不多说,直接上代码:

class ExceptionChange:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_template_response(self, request, response):
        if hasattr(response, 'data'):
            data = response.data
            print(type(data))
            if "non_field_errors" in data.keys():
                if data['non_field_errors'] == ["无法使用提供的认证信息登录。"]:
                    del response.data['non_field_errors']
                    response.data['msg'] = '用户名或者密码错误'
                    response.data['status'] = '400'
            elif "detail" in data.keys():
                del response.data["detail"]
                response.data["status"] = response.status_code
                response.data["msg"] = "请先登录系统"
        return response

然后前往setting中将该方法配置到middleware中去,这里值得注意的是,django的middleware调用方法是请求的时候从上往下,返回的时候从下往上,所以这里我们直接将我们的方法放到最下方:
image.png
对于这两种方法我更倾向于第二种,因为这样通过middleware的修改返回值的好处不关可以处理jwt的登录请求,还能将django其他的失败返回也进行处理,这样可以更方便的进行我们的接口定制,当然因为我是一个初学者,我不知道其他的返回信息有没有更好的修改方法,当然如果有大佬知道其他更好的办法欢迎留言。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值