微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Django Rest Framework PyJWT 令牌无效的标头填充

如何解决Django Rest Framework PyJWT 令牌无效的标头填充

我正在使用 Django Rest Frame Work,我正在尝试使用会话中的令牌获取经过身份验证的用户信息

views.py:

# Get Authenticated User Data
class UserAPIView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self,request):
        return Response(UserSerializer(request.user).data)

JWTAuthentication

class JWTAuthentication(BaseAuthentication):

    def authenticate(self,request):
        token = request.COOKIES.get('jwt')
        print('token = ',token)

        if not token:
            return None

        try:
            payload = jwt.decode(token,settings.SECRET_KEY,algorithms=['HS256'])
            print('payload = ',payload)
        except jwt.ExpiredSignatureError:
            raise exceptions.AuthenticationFailed('unauthenticated')

        user = User.objects.get(pk=payload['user_id'])

        if not user:
            raise exceptions.AuthenticationFailed('User not found!')

        return (user,None)

    @staticmethod
    def generate_jwt(id):
        payload = {
            'user_id': id,'exp': datetime.datetime.Now() + datetime.timedelta(days=1),'iat': datetime.datetime.utcNow()
        }
        return jwt.encode(payload,algorithm='HS256')

但是我遇到了这个错误

Invalid header padding 

这是回溯

[08/Jun/2021 10:44:09] "GET /api/account/user/ HTTP/1.1" 500 134862
token =  b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE2MjMyMzU0NDcsImlhdCI6MTYyMzE0MTg0N30.qnNZw3M5YiLMalc78wknjtuTOztHbjyr2swHyK1xuGY'
Internal Server Error: /api/account/user/
Traceback (most recent call last):
  File "C:\Users\MAbbas\AppData\Local\Programs\Python\python37\lib\site-packages\jwt\api_jws.py",line 186,in _load
    header_data = base64url_decode(header_segment)
  File "C:\Users\MAbbas\AppData\Local\Programs\Python\python37\lib\site-packages\jwt\utils.py",line 42,in base64url_decode
    return base64.urlsafe_b64decode(input)
  File "C:\Users\MAbbas\AppData\Local\Programs\Python\python37\lib\base64.py",line 133,in urlsafe_b64decode
    return b64decode(s)
  File "C:\Users\MAbbas\AppData\Local\Programs\Python\python37\lib\base64.py",line 87,in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Invalid base64-encoded string: number of data characters (37) cannot be 1 more than a multiple of 4

这是 Traceback 的其余部分

在处理上述异常的过程中,又发生了一个异常:

  File "D:\Private\PythonProjects\ProCoders-02\src\Pepsi\profession\backend\blog\api\API_Authentication.py",line 20,in authenticate
    payload = jwt.decode(token,algorithms=['HS256'])
  File "C:\Users\MAbbas\AppData\Local\Programs\Python\python37\lib\site-packages\jwt\api_jwt.py",line 84,in decode
    payload,_,_ = self._load(jwt)
  File "C:\Users\MAbbas\AppData\Local\Programs\Python\python37\lib\site-packages\jwt\api_jws.py",line 188,in _load
    raise DecodeError('Invalid header padding')
jwt.exceptions.DecodeError: Invalid header padding

修改 No.01(添加了 LogInView 以显示我如何保存令牌)

登录查看

class LoginAPIView(APIView):
    def post(self,request):
        email = request.data['email']
        password = request.data['password']

        user = User.objects.filter(email=email).first()

        if user is None:
            raise exceptions.AuthenticationFailed('User not found!')

        if not user.check_password(password):
            raise exceptions.AuthenticationFailed('Incorrect Password!')

        token = JWTAuthentication.generate_jwt(user.id)

        response = Response()
        response.set_cookie(key='jwt',value=token,httponly=True)
        response.data = {
            'message': 'success'
        }

        return response

令牌存在于 cookie 中并如您所见打印,但是这个错误让我很生气 提前致谢

解决方法

尝试在编码时将令牌解码为utf-8

返回 jwt.encode(payload,settings.SECRET_KEY,algorithm='HS256').decode("utf-8")

并检查它是否有效

此处有更多信息https://github.com/jpadilla/pyjwt/issues/319

,

我认为问题可能在于您编码 jwt 的方式,在您的有效负载中尝试将“exp”值转换为 int 值,如下所示: 有效载荷 = { 'user_id': id,'exp': int(datetime.datetime.now() + datetime.timedelta(days=1)),'iat': int(datetime.datetime.utcnow()) } 返回 jwt.encode(payload,algorithm='HS256')

我相信 exp 和 iat 值必须是数字

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。