Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

canot set authorization header #3196

Closed
ioistired opened this issue Aug 16, 2018 · 8 comments
Closed

canot set authorization header #3196

ioistired opened this issue Aug 16, 2018 · 8 comments
Labels

Comments

@ioistired
Copy link

Long story short

Cannot set the Authorization header with this code.

Steps to reproduce

import asyncio
 
import aioec
 
loop = asyncio.get_event_loop()
client = aioec.Client(token='BNI=;6pXUYxftBItgvTAtN6X7bDGDluCnEwOnavKG9i3A4MY=', loop=loop)
 
print(loop.run_until_complete(client.login()))

That is a test token, and safe to reproduce. It has no access other than authorization.

Expected behaviour

1234 is outputted.

Actual behaviour

aioec.errors.LoginFailure: Invalid or incorrect token has been passed. is outputted

Reason

It seems that the Authorization header is not being set. printing response.request_info.headers['Authorization'] inside aioec/http.HttpClient.request raises a KeyError: "Key not found: 'Authorization'", even though the headers are clearly set in aioec/http.py at 5ae0994 L47-L151 and I can confirm that self._session._default_headers['Authorization'] is set.

Workaround

Downgrade to aiohttp>=2.0.0,<2.3.0 and yarl<1.2.
This is why I believe the issue to be aiohttp based and not in my code, unless I'm using aiohttp incorrectly.

Your environment

aiohttp version: 3.3.2
OS: Ubuntu 18.04 LTS
Python: 3.6.5

@Maillol
Copy link
Contributor

Maillol commented Aug 16, 2018

It seems to work with 3.3.2 on python 3.5.6 and 3.7.0

import aiohttp
import asyncio

async def test():
    session = aiohttp.ClientSession(
        headers={'Authorization': 'BNI=;6pXUYxftBItgvTAtN6X7bDGDluCnEwOnavKG9i3A4MY='})

    url = 'https://emoji-connoisseur.python-for.life/api/v0/login'
    async with session.request('GET', url) as response:
        print(await response.text())
        await session.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(test())

Is there any difference between your code and this snippet ?

@ioistired
Copy link
Author

Hmmmm I tried this code too:

#!/usr/bin/env python3
# encoding: utf-8

import asyncio

import aiohttp

class HttpClient:
	def __init__(self, token=None, *, loop=None):
		self.loop = loop or asyncio.get_event_loop()

		self.session = aiohttp.ClientSession(
			headers={'Authorization': 'BNI=;6pXUYxftBItgvTAtN6X7bDGDluCnEwOnavKG9i3A4MY='},
			loop=self.loop)

	async def login(self):
		async with self.session.request('GET', 'https://emoji-connoisseur.python-for.life/api/v0/login') as resp:
			print(resp.status)
			return await resp.text()

if __name__ == '__main__':
	loop = asyncio.get_event_loop()
	print(loop.run_until_complete(HttpClient().login()))

And it worked. What gives?

@ioistired
Copy link
Author

Ok, here's another case which does not reproduce the issue.

#!/usr/bin/env python3
# encoding: utf-8

import asyncio

import aiohttp

class HttpClient:
	def __init__(self, token=None, *, loop=None):
		self.loop = loop or asyncio.get_event_loop()

		headers = {}
		if token is not None:
			headers['Authorization'] = token

		self.session = aiohttp.ClientSession(
			headers=headers,
			loop=self.loop)

	async def request(self, method, url, **kwargs):
		async with self.session.request(method, url, **kwargs) as resp:
			print(resp.status)
			return await resp.text()

	def login(self):
		return self.request('GET', 'https://emoji-connoisseur.python-for.life/api/v0/login')

if __name__ == '__main__':
	import sys

	token = sys.argv[1]
	loop = asyncio.get_event_loop()
	print(loop.run_until_complete(HttpClient(token=token, loop=loop).login()))

There must be a curse on my code then, cause this code is very close to what I have written.

@MyNameIsCosmo
Copy link

MyNameIsCosmo commented Aug 16, 2018

https://github.com/EmojiConnoisseur/aioec/blob/master/aioec/http.py#L29

In your tests above, you're calling the https socket, though in aioec, you're calling http.

Edit:
Changing your above request urls to http://emoji-... results in:

401
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7feb251576d8>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7feb22808e10>, 1464675.070069642)]']
connector: <aiohttp.connector.TCPConnector object at 0x7feb25157710>
{"status": 401, "message": "no token provided"}

@ioistired
Copy link
Author

Thank you.

@brncsk
Copy link

brncsk commented May 21, 2019

@bmintz Sorry for reviving an old thread. Does this mean there is no way to set the Authorization header when using HTTP? Is this a protocol limitation or one imposed by aiohttp itself? I couldn't find much on this topic.

@ioistired
Copy link
Author

There's no such limitation imposed by either. This issue was entirely user error.

@brncsk
Copy link

brncsk commented May 21, 2019

@bmintz Thanks for the clarification.

@lock lock bot added the outdated label May 20, 2020
@lock lock bot locked as resolved and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants