简体   繁体   English

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

[英]How to extract jwt token payload when token is expired in python jwt

I am unable to extract JWT token payload after the jwt token expires in python jwt package. I am using flask api for backend development and the implementation is in the middleware.在 jwt 令牌在 python jwt package 中过期后,我无法提取 JWT 令牌有效载荷。我正在使用 flask api 进行后端开发和实现。

Below is my code:下面是我的代码:

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

I have found out the solution in the jwt package in python.我在python的jwt包中找到了解决方案。 Below is the link for reference: https://pyjwt.readthedocs.io/en/latest/usage.html#reading-the-claimset-without-validation以下是参考链接: https : //pyjwt.readthedocs.io/en/latest/usage.html#reading-the-claimset-without-validation

Below is the code change which I did for the above:以下是我为上述所做的代码更改:

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

After merging the code with the main code it looks like below:将代码与主代码合并后,如下所示:

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

There is alternative way to decode the jwt token if it is expired: As suggested by @KlausD.如果 jwt 令牌过期,还有其他方法可以对其进行解码:正如@KlausD 所建议的那样。 Below is the implementation:下面是实现:

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

Thanks to @KlausD.感谢@KlausD。 for the simple hack对于简单的黑客

If the options parameter doesn't work like this: options = { "verify_signature": False }如果 options 参数不能像这样工作:options = { "verify_signature": False }

Using the lib pyjwt==1.7.1 try to inform the parameter "verify=False", like this here:使用 lib pyjwt==1.7.1 尝试通知参数“verify=False”,如下所示:

payload = jwt.decode(jwt=token, key=secret, verify=False, algorithms = [ 'HS256' ]) payload = jwt.decode(jwt=token, key=secret, verify=False, 算法= [ 'HS256' ])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM