【问题标题】:Flask werkzeug request.authorization is none but Authorization headers presentFlask werkzeug request.authorization 没有,但存在授权标头
【发布时间】:2015-02-22 04:07:10
【问题描述】:

我正在发布一些 JSON 数据并添加 Authorization 标头。但是,请求对象没有正确的授权属性。 HTTP_AUTHORIZATION 和 headers 都显示正确的授权详细信息。

{'authorization': None,
 'cookies': {},
 'environ': {'CONTENT_LENGTH': '81',
             'CONTENT_TYPE': u'application/json',
             'HTTP_AUTHORIZATION': 'testkey:',
             'HTTP_CONTENT_LENGTH': '81',
             'HTTP_CONTENT_TYPE': 'application/json',
             'HTTP_HOST': 'test',
             'PATH_INFO': '/v1/test',
             'QUERY_STRING': '',
             'REQUEST_METHOD': 'POST',
             'SCRIPT_NAME': '',
             'SERVER_NAME': 'test',
             'SERVER_PORT': '80',
             'SERVER_PROTOCOL': 'HTTP/1.1',
             'flask._preserve_context': False,
             'werkzeug.request': <Request 'http://test/v1/test' [POST]>,
             'wsgi.errors': <open file '<stderr>', mode 'w' at 0x10d5471e0>,
             'wsgi.input': <_io.BytesIO object at 0x11074c410>,
             'wsgi.multiprocess': False,
             'wsgi.multithread': False,
             'wsgi.run_once': False,
             'wsgi.url_scheme': 'http',
             'wsgi.version': (1, 0)},
 'headers': EnvironHeaders([('Authorization', testkey:'), ('Host', u'test'), ('Content-Length', u'81'), ('Content-Type', u'application/json')]),
 'shallow': False,
 'url': u'http://test/v1/test',
 'url_rule': <Rule '/v1/test' (POST, OPTIONS) -> testresource>,
 'view_args': {}}

【问题讨论】:

  • 请您添加实际的控制台/网络视图错误
  • @Ondeckshooting - 没有错误。请阅读问题。问题是授权属性是无,但正确的标头在那里。

标签: flask werkzeug


【解决方案1】:

request.authorization 属性仅在您具有有效的Basic Authorization 或Digest Authorization 标头时设置; Authorization 标头具有特定格式,其中标头值中的第一个单词设置类型,并且该属性仅处理这两种特定类型(由 Basic 或 Digest 类型关键字标记)。

来自AuthorizationMixin.authorization attribute documentation

已解析形式的授权对象。

接着Authorization object docs:

表示客户端发送的授权标头。您不应该自己创建这种对象,而是在 parse_authorization_header 函数返回时使用它。

这是documented as:

解析由网络浏览器传输的HTTP基本/摘要授权标头。如果标头无效或未给出,则返回值为 None,否则为 Authorization 对象。

我的大胆强调。

您的标头不是这样有效的标头;它没有Basic 或Digest 类型指示符。如果您确实有这样的标题,则该函数会返回None以外的其他内容:

>>> from werkzeug.http import parse_authorization_header
>>> parse_authorization_header('testkey:')
>>> parse_authorization_header('testkey:') is None
True
>>> parse_authorization_header('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==')
{'username': 'Aladdin', 'password': 'open sesame'}
>>> result = _
>>> type(result)
<class 'werkzeug.datastructures.Authorization'>
>>> result.username
'Aladdin'
>>> result.password
'open sesame'

我在那里使用了Basic 类型的标头,其中标头值的其余部分是由: 冒号分隔的base-64 编码的用户名和密码对。

如果您想实现自己的身份验证方案,只需访问标头本身并手动解析即可。

auth = request.headers.get('authorization')

【讨论】:

    【解决方案2】:

    在使用 apache+WSGI 时,不要忘记 WSGIPassAuthorization On 指令。

    【讨论】:

    • 这对我很有帮助,谢谢。出于好奇,为什么在 apache 中默认不传递授权标头(或者是 wsgi 阻止它)?
    • 我也很好奇:modwsgi.readthedocs.io/en/develop/configuration-directives/… 默认情况下不会传递授权标头,因为这样做可能会将有关密码的信息泄漏到 WSGI 应用程序,当 Apache 执行授权时该应用程序无法看到它们.如果 Apache 正在执行授权,WSGI 应用程序仍然可以通过检查 WSGI 应用程序环境的变量 AUTH_TYPE 来找出使用了哪种类型的授权方案...
    • 非常感谢!它为我节省了很多时间!
    【解决方案3】:

    您的授权标头 ('Authorization', 'testkey:') 需要经过 Base64 编码并包含 Basic。

    在python中:

    import base64
    base64.b64encode('testkey:') # 'dGVzdGtleTo='
    

    在 javascript 中使用 btoa:

    设置标题
    '{"Authorization": "Basic ' + btoa('testkey:') + '"}' 
    '{"Authorization": "Basic dGVzdGtleTo="}' 
    

    在你的情况下,这将导致标题进入:

    ('Authorization', 'Basic dGVzdGtleTo=')

    【讨论】:

    • 需要 Base64 编码并包含 Basic 是它的关键,示例:{"Authorization": "Basic dGVzdGtleTo='"} 否则它将显示在 request.environ['HTTP_AUTHORIZATION'] 下
    • Bearer token 也可以用同样的方式发送,但这里不需要 Base64 编码虽然{"Authorization": "Bearer AbCdEf123456"}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 2020-05-08
    • 2020-11-13
    • 2022-01-06
    • 2019-07-23
    • 2021-10-18
    • 1970-01-01
    相关资源
    最近更新 更多