【问题标题】:How to use a dict returned by a decorator as a variable?如何使用装饰器返回的字典作为变量?
【发布时间】:2021-02-27 16:55:51
【问题描述】:

我正在使用flask-restx 开发一个烧瓶应用程序。在那里,我想用一个名为 cognito_check_groups 的装饰器来装饰路由,该装饰器检查令牌、验证它并返回声明。

我想知道有没有办法可以将返回的claims 保存为变量,以便我可以进一步使用它的内容

我的代码:

def cognito_check_groups(groups: list):
    def decorator(function):
        def wrapper(*args, **kwargs):
            _cognito_check_groups(groups)
            return function(*args, **kwargs)
        return wrapper
    return decorator

def _cognito_check_groups(groups: list):

    token = None
    if 'x-access-token' in request.headers:
        token = request.headers['x-access-token']

    if not token:
        return abort(
            401,
            'Missing token'
        )

    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']
    
    key_index = -1
    for i in range(len(keys)):
        if kid == keys[i]['kid']:
            key_index = i
            break
    if key_index == -1:
        print('Public key not found in jwks.json')
        return False

    public_key = jwk.construct(keys[key_index])
    message, encoded_signature = str(token).rsplit('.', 1)
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
    
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        print('Signature verification failed')
        return False
    print('Signature successfully verified')
    
    claims = jwt.get_unverified_claims(token)
    return claims

我使用的装饰器如下:

@crud_ns.route("/insert")
class InsertVendor(Resource):
    @crud_ns.doc(
        "Insert data into the DB",
        responses={
            200: "Values returned",
            400: "Validation Error",
            401: "Not authorized",
            409: "Conflct"
        },
    )
    @crud_ns.doc(security='apikey')
    @crud_ns.expect(crud_insert_parser, validation=True)
    @cognito_check_groups(['admin'])
    def post(self):
        args = crud_insert_parser.parse_args()
        return Insert.insert(**args)

【问题讨论】:

    标签: python python-3.x decorator python-decorators


    【解决方案1】:

    虽然我对 Flask 了解不多,但通常你可以这样:

    def cognito_check_groups(groups: list):
        def decorator(function):
            def wrapper(*args, **kwargs):
                claims = _cognito_check_groups(groups)
                # add claims to kwargs!
                kwargs.update({'claims': claims})
                return function(*args, **kwargs)
            return wrapper
        return decorator
    
    ...
    @cognito_check_groups(['admin'])
    def post(self, *args, **kwargs):
        claims = kwargs.get('claims', {})
        args = crud_insert_parser.parse_args()
        return Insert.insert(**args)
    

    【讨论】:

    • 您好,谢谢您的回复。我试过你的建议,它给出了以下错误TypeError: post() argument after ** must be a mapping, not NoneType
    • @reinhardt:已更新,我们无法即时更新**kwargs :)
    猜你喜欢
    • 2021-02-27
    • 2021-06-24
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    • 2020-02-10
    • 1970-01-01
    相关资源
    最近更新 更多