Python 通过装饰器从令牌中提取用户id
我正在开发使用auth0进行身份验证和授权的flask RESTful应用程序。然后,我编写了一个decorator来验证令牌并从中提取用户id。我的目标是使用从令牌中提取的id在修饰函数中使用,如果来自令牌和来自URL参数的用户id不匹配,则引发异常。这是为了避免用户使用自己的令牌更改另一个用户的数据。我不确定这是否是RESTful应用程序的最佳实践,但在我的情况下似乎需要这样做 也就是说,我试图找出将用户id从令牌传递到修饰函数的最佳方法: 大概是这样的:Python 通过装饰器从令牌中提取用户id,python,rest,flask,Python,Rest,Flask,我正在开发使用auth0进行身份验证和授权的flask RESTful应用程序。然后,我编写了一个decorator来验证令牌并从中提取用户id。我的目标是使用从令牌中提取的id在修饰函数中使用,如果来自令牌和来自URL参数的用户id不匹配,则引发异常。这是为了避免用户使用自己的令牌更改另一个用户的数据。我不确定这是否是RESTful应用程序的最佳实践,但在我的情况下似乎需要这样做 也就是说,我试图找出将用户id从令牌传递到修饰函数的最佳方法: 大概是这样的: def authorization
def authorization():
def inner(func):
def wrapper(*args, **kwargs):
try:
"""
token validation stuff
...
"""
wrapper.user_id = token_payload['user_id']
except Exception:
return {"success": False}, 500
return func(*args, **kwargs)
return wrapper
return inner
@authorization()
@app.route('/test', methods=['GET'])
def some_function():
return jsonify({
'success': True,
'user_id': some_function.user_id
})
如您所见,我将user_id字段设置为包装器函数,这似乎不是最好的方法。对这种情况有什么不同的处理方法吗?也许是使用烧瓶资源
functools.wrapps
更新已包装函数的签名,使内省和调试更容易现在,您使用
@authorized
装饰的每个函数都需要将用户id
作为其第一个参数,并且所有功能都应该按照您的预期工作。这是一个很好的观点。我真正的装饰器有参数,我考虑在kwargs中传递id,如果我这样做,装饰的每个函数都必须有**kwargs作为参数,即使我不需要该id该函数。@MatheusHernandes如果你有一些函数需要授权,但不需要用户id
,您也可以将其作为装饰器的参数。类似于@authorized(pass\u id=True)
然后调用func(user\u id,…)
或仅仅调用func(…)
,具体取决于此。可能是。。。我介于那个选择和另一个选择之间question@MatheusHernandes如果您希望以更结构化的方式执行此操作,您可以使用before\u request
处理程序来处理授权内容,并将user\u id
放入flask.g
应用程序上下文命名空间。然后,您可以为需要授权的路由注册一个单独的蓝图
,该路由在请求前使用预处理器。
from functools import wraps
def authorized(func):
@wraps(func)
def wrapper(*args, **kw):
try:
# token stuff
user_id = token_payload['user_id']
except:
return jsonify({"success": False}), 500
return func(user_id, *args, **kw)
return wrapper
@app.route('/test', methods=['GET'])
@authorized
def some_function(user_id):
return jsonify({
'success': True,
'user_id': user_id
})