首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django Rest框架PyJWT令牌报头填充无效

Django Rest框架PyJWT令牌报头填充无效
EN

Stack Overflow用户
提问于 2021-06-08 17:40:59
回答 2查看 453关注 0票数 0

我正在使用Django Rest框架,并且我正在尝试使用会话中的令牌来获取经过身份验证的用户信息

views.py:

代码语言:javascript
复制
# Get Authenticated User Data
class UserAPIView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

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

JWTAuthentication

代码语言:javascript
复制
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, settings.SECRET_KEY, algorithm='HS256')

但是我得到了这个错误

代码语言:javascript
复制
Invalid header padding 

这是回溯

代码语言:javascript
复制
[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

这是回溯的其余部分

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

代码语言:javascript
复制
  File "D:\Private\PythonProjects\ProCoders-02\src\Pepsi\profession\backend\blog\api\API_Authentication.py", line 20, in authenticate
    payload = jwt.decode(token, settings.SECRET_KEY, 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

修改编号01(添加LogInView以显示我是如何保存令牌的)

LogInView

代码语言:javascript
复制
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中,并且如您所见打印出来,但是这个错误让我提前疯狂地致谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-08 20:01:26

对令牌进行编码时,请尝试将其解码为utf-8

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

并检查它是否正常工作

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

票数 0
EN

Stack Overflow用户

发布于 2021-06-08 20:22:27

我认为问题可能出在编码jwt的方式上,在有效负载中尝试将‘exp’值转换为int值,如下所示: payload ={ 'user_id':id,'exp':int(datetime.datetime.now() + datetime.timedelta(days=1)),'iat':int(datetime.datetime.utcnow()) } return jwt.encode( payload,settings.SECRET_KEY,algorithm='HS256')

我认为exp和iat值必须是数字。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67885164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档