You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

密码更改API中JWT解码报错:Token必须为bytes类型的问题求助

解决JWT解码时的"令牌必须属于bytes类"错误

这个报错的核心原因是PyJWT库的jwt.decode()方法要求传入的密钥必须是bytes类型,而你直接使用了字符串格式的settings.SECRET_KEY,同时也需要确保传入的token本身是有效的字符串(避免空值或格式错误)。下面是具体的修复步骤:

1. 核心修复:转换密钥为bytes类型

修改jwt.decode的调用代码,把settings.SECRET_KEY通过encode('utf-8')转换为bytes格式,这是解决当前报错的关键:

payload = jwt.decode(serializer['token'], settings.SECRET_KEY.encode('utf-8'), algorithms=['HS256'])

2. 优化代码:增加健壮性检查

为了避免其他潜在问题(比如token无效、用户不存在等),建议补充异常捕获和前置检查,让API返回更友好的错误信息:

from rest_framework import status
from rest_framework.response import Response
import jwt

class PasswordChange(generics.GenericAPIView):
    model = CustomUser
    serializer_class = PasswordChangeSerializer
    
    def patch(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        # 提取token并做非空检查
        token = serializer.get('token')
        if not token:
            return Response({"error": "Token is required"}, status=status.HTTP_400_BAD_REQUEST)
            
        try:
            # 转换密钥为bytes后执行解码
            payload = jwt.decode(token, settings.SECRET_KEY.encode('utf-8'), algorithms=['HS256'])
        except jwt.InvalidTokenError as e:
            return Response({"error": f"Invalid token: {str(e)}"}, status=status.HTTP_401_UNAUTHORIZED)
            
        try:
            user = CustomUser.objects.get(id=payload['user_id'])
        except CustomUser.DoesNotExist:
            return Response({"error": "User not found"}, status=status.HTTP_404_NOT_FOUND)
            
        if user.check_password(serializer['old_password']):
            user.set_password(serializer['new_password'])
            user.save()
            return Response({"message": "Password changed successfully"}, status=status.HTTP_200_OK)
        else:
            return Response({"error": "Old password is incorrect"}, status=status.HTTP_400_BAD_REQUEST)

补充说明

  • 如果你使用的是PyJWT 2.0+版本,理论上已经支持字符串类型的密钥,但部分环境下可能因为编码问题仍需要显式转换为bytes,所以上面的修复方案兼容新旧版本。
  • 你已经使用了serializer.is_valid(raise_exception=True)来确保请求数据合法性,这一步做得很到位,能提前拦截无效的请求参数。

内容的提问来源于stack exchange,提问作者Aman Arora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:02:41