更改/替换Flask中的不可变请求对象

时间:2014-05-29 10:37:00

标签: python oauth flask immutability werkzeug

目前,我正在为非REST API开发Oauthlib-Flask实现。但我有两个场景,我想更改/添加烧瓶请求对象的值。由于它是不可改变的,所以并不容易。我尝试在Changing values on a werkzeug request object中建议复制。但由于@oauth.authorize_handler使用给定的请求对象,我必须替换它,它会在UnboundLocalError: local variable 'request' referenced before assignment错误中解决。这是我的示例代码(它是隐式授权的一部分):

@app.route('/oauth/authorize', methods=['GET', 'POST'])
@login
@oauth.authorize_handler
def authorize(*args, **kwargs):
    if request.method == 'GET':
        client_id = kwargs.get('client_id')
        client = Client.query.filter_by(client_id=client_id).first()
        kwargs['client'] = client
        return render_template('authorize.html', **kwargs)

    r = make_duplicate_request(request)
    #Change/add values of r
    request = r
    return True

我做错了什么或是否有其他可能更改请求对象?

感谢您的帮助!

更新: 上面的代码描述了我想将信息传递给tokensetter函数的情况。这可以通过全局变量来完成,但我想避免这种情况。

在我的注册例程中,客户端将这样的请求发送到API:

params_signup = {
    "schemas":["urn:scim:schemas:core:2.0:User"],
    "expireIn":3600,
    "username":"test@web.de",
    "password":"123",
    "access_token":"",
    "externalId":"tmeinhardt",
    "grant_type":"password",
    "client_id":"1",           
    "params":{
        "age":"20-30",
        "gender":"m",
        }
   }

我只需要{token}处理程序的grant_typeclient_id部分,并希望将其手动添加到请求对象中。但是因为这个对象是不可变的......

1 个答案:

答案 0 :(得分:1)

为那些会遇到这个问题并试图实现 OAuth 流程的人写这篇文章。

不要使用装饰器,而是使用中间件

我相信您应该在中间件中处理这个问题。在中间件中,您可以设置 call 函数的第二个参数的授权属性,该函数包含您在 init 函数中传递的当前 wsgi 应用程序环境变量。 看下面的代码:

def __init__(self, app):
    self.app = app

def __call__(self, environ, start_response):
    cookie = Request(environ).cookies.get('access_token')
    if cookie is not None:
        environ['HTTP_AUTHORIZATION']='Bearer '+cookie
    return self.app(environ, start_response)