密码更改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
相关产品推荐
相关产品推荐

