python jwt中令牌过期时如何提取jwt令牌有效负载

Posted

技术标签:

【中文标题】python jwt中令牌过期时如何提取jwt令牌有效负载【英文标题】:How to extract jwt token payload when token is expired in python jwt 【发布时间】:2021-12-24 05:21:50 【问题描述】:

在 python jwt 包中的 jwt 令牌过期后,我无法提取 JWT 令牌有效负载。 我正在使用flask api进行后端开发,实现在中间件中。

下面是我的代码:

import jwt
from flask import request
from functools import wraps
from werkzeug.exceptions import Forbidden, Unauthorized

def admin_rights_required(f):
    @wraps(f)
    def _decorated(*args, **kwargs):
        config = readConfig()
        secretKey = config["JWT_SECRET_KEY"]
        algorithm = config["JWT_ENCODING_ALGORITHM"]
        token = None
        if "Authorization" in request.headers:
            data = request.headers["Authorization"]
            token = str.replace(str(data), "Bearer ", "")
        try:
            if not token or (not _ruleUserObj.getRuleUserFromToken(token)):
                data = jwt.decode(token, secretKey, algorithms=algorithm)
                raise Unauthorized("Token is missing")
            data = jwt.decode(token, secretKey, algorithms=algorithm)
            if getTokenDurationDifference(token) == -1:
                raise jwt.InvalidTokenError
            currentUser = _ruleUserObj.getRuleUser(data["sub"]["username"])
            if not len(currentUser) > 0:
                raise jwt.InvalidTokenError
            if currentUser["isAdmin"] == False:
                raise Forbidden()
        except jwt.ExpiredSignatureError:
            _ruleUserObj.updatedRuleUserSessionRemToken(data["sub"]["username"])
            raise Unauthorized("Signature expired. Please log in again.")
        except jwt.InvalidTokenError:
            _ruleUserObj.updatedRuleUserSessionRemToken(data["sub"]["username"])
            raise Unauthorized("Invalid token. Please log in again.")

        return f(*args, **kwargs)

    return _decorated

【问题讨论】:

按点分割,中间部分base64解码,json解码。 你能举个同样@KlausD的例子吗? 可以尝试实现吗? 已更新答案并进行了尝试,它按预期工作。再次感谢@KlausD 的简单破解。 【参考方案1】:

我在python的jwt包里找到了解决办法。以下是供参考的链接: https://pyjwt.readthedocs.io/en/latest/usage.html#reading-the-claimset-without-validation 以下是我为上述所做的代码更改:

jwt.decode(
                        token,
                        secretKey,
                        algorithms=algorithm,
                        options="verify_signature": False,
                    )
                )["sub"]["username"]
            )

将代码与主代码合并后如下所示:

import jwt
from flask import request
from functools import wraps
from werkzeug.exceptions import Forbidden, Unauthorized

def admin_rights_required(f):
    @wraps(f)
    def _decorated(*args, **kwargs):
        config = readConfig()
        secretKey = config["JWT_SECRET_KEY"]
        algorithm = config["JWT_ENCODING_ALGORITHM"]
        token = None
        if "Authorization" in request.headers:
            data = request.headers["Authorization"]
            token = str.replace(str(data), "Bearer ", "")
        try:
            if not token or (not _ruleUserObj.getRuleUserFromToken(token)):
                data = jwt.decode(token, secretKey, algorithms=algorithm)
                raise Unauthorized("Token is missing")
            data = jwt.decode(token, secretKey, algorithms=algorithm)
            if getTokenDurationDifference(token) == -1:
                raise jwt.InvalidTokenError
            currentUser = _ruleUserObj.getRuleUser(data["sub"]["username"])
            if not len(currentUser) > 0:
                raise jwt.InvalidTokenError
            if currentUser["isAdmin"] == False:
                raise Forbidden()
        except jwt.ExpiredSignatureError:
            _ruleUserObj.updatedRuleUserSessionRemToken(
                (
                    jwt.decode(
                        token,
                        secretKey,
                        algorithms=algorithm,
                        options="verify_signature": False,
                    )
                )["sub"]["username"]
            )
            raise Unauthorized("Signature expired. Please log in again.")
        except jwt.InvalidTokenError:
            _ruleUserObj.updatedRuleUserSessionRemToken(
                (
                    jwt.decode(
                        token,
                        secretKey,
                        algorithms=algorithm,
                        options="verify_signature": False,
                    )
                )["sub"]["username"]
            )
            raise Unauthorized("Invalid token. Please log in again.")

        return f(*args, **kwargs)

    return _decorated

如果 jwt 令牌已过期,还有另一种解码方法: 正如@KlausD 所建议的那样。下面是实现:

import base64
import json
tokenSplit = token.split(".")
json.loads((base64.b64decode(tokenSplit[1])).decode("utf-8"))

感谢@KlausD。对于简单的黑客攻击

【讨论】:

以上是关于python jwt中令牌过期时如何提取jwt令牌有效负载的主要内容,如果未能解决你的问题,请参考以下文章

如何在jwt中过期时刷新令牌

我如何在 jwt 令牌中设置过期 30 分钟

如何手动使 JWT 令牌过期?

Webapi 2.0如何在访问令牌过期时实现刷新JWT令牌

当用户在nodeJS / Express和Angular中空闲一段时间(基于令牌的授权)时,我如何使我的JWT令牌过期

单元测试 JWT 令牌过期:Django REST