I am POSTing some JSON data and adding an Authorization
header. However, the request object does not have the correct authorization property. HTTP_AUTHORIZATION
and headers
both show the proper authorization details.
{'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': {}}
The request.authorization
attribute is only set when you have a valid Basic Authorization or Digest Authorization header; the Authorization
header has specific formats where the first word in the header value sets the type, and the attribute only handles those two specific types (flagged by the Basic
or Digest
type keywords).
From the AuthorizationMixin.authorization
attribute documentation
The Authorization object in parsed form.
following that to the Authorization
object docs:
Represents an Authorization header sent by the client. You should not create this kind of object yourself but use it when it’s returned by the parse_authorization_header function.
which is documented as:
Parse an HTTP basic/digest authorization header transmitted by the web browser. The return value is either None if the header was invalid or not given, otherwise an
Authorization
object.
Bold emphasis mine.
Your header is not such a valid header; it is doesn't have the Basic
or Digest
type indicator. If you did have such a header the function returns something other than 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'
I used a Basic
type header there, where the remainder of the header value is a base-64 encoded username and password pair separated by a :
colon.
If you want to implement your own authentication scheme, just access the header itself and parse it manually.
auth = request.headers.get('authorization')
Your authorization header ('Authorization', 'testkey:')
needs to be Base64 encoded and include Basic
.
in python:
import base64
base64.b64encode('testkey:') # 'dGVzdGtleTo='
in javascript set your header using btoa
:
'{"Authorization": "Basic ' + btoa('testkey:') + '"}'
'{"Authorization": "Basic dGVzdGtleTo="}'
In your case, the this will result in the header coming in as:
('Authorization', 'Basic dGVzdGtleTo=')
When using apache+WSGI, don't forget the WSGIPassAuthorization On
directive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With