烧瓶JWT到SQLAlchemy用户对象?

时间:2020-08-07 12:49:02

标签: authentication flask sqlalchemy jwt authorization

我有一个应用程序,其中用户详细信息作为JWT传递,其中包含有关当前用户及其角色的信息。 每当用户登录时(通过KeyCloak实例),来自JWT的信息都会在我端解析为一个函数,该函数通过SQLAlchemy更新用户对象。但是,由于没有在后端来回传递用户对象,因此我必须解析JWT以获取需要它的每个操作的角色。我也需要审核,并且由于应用程序的结构,该模块在登录时不一定可以访问请求对象。

我正在寻找一种巧妙的方法,通过映射JWT-> ORM用户对象来使flask_user的{​​{1}}功能类似,从而能够透明地获取当前用户。有什么办法可以解决这个问题吗?用户注册等与应用程序完全分开,current_user()仅基于正在发送的请求中的令牌知道它是哪个用户。

TLDR;是否有一种方法可以基于已发布的JWT(其中包含要映射到用户的信息)从数据库加载用户,并且也许已经存在支持该功能的flask的lib或扩展吗?

2 个答案:

答案 0 :(得分:0)

我使用装饰器通过pyjwt解析JWT令牌。

然后从解析的令牌中获取用户并进行适当的授权。

如果您不想将装饰器添加到所有需要授权的功能中,则可以使用Flasks before_request

from functools import wraps

from flask import Response, current_app, request
from jwt import decode
from jwt.exceptions import (DecodeError, ExpiredSignatureError,
                            InvalidSignatureError)

def authorize(func):

    @wraps(func)
    def check_authorization(*args, **kwargs):
        try:
            jwt_token = request.cookies.get('auth_token') # get token from request
            if jwt_token is None:
                return Response(status=401, headers={'WWW-Authenticate': 'Bearer'})
            
            token = decode(
                jwt_token,
                key='pub_key', # public key to validate key
                algorithms=['RS256'], # list of algs the key could be signed 
                verify=True
            )
            
            # you can call another function to do check user roles here
            # e.g authorize(token['sub'])
            
            return func(*args, **kwargs)
        except (InvalidSignatureError, DecodeError, ExpiredSignatureError):
            return Response(
                response='{ "error": "token_invalid"}',
                status=401,
                headers={'WWW-Authenticate': 'Bearer'})
    return check_authorization

答案 1 :(得分:0)