OAuth for your aiohttp web application
It’s pretty easy and convenient to use authorization on you service with a help of third party oauth services using popular web frameworks such as Flask (Flask-OAuthlib). There are a lot of tutorials and examples for them but what about aiohttp?
In this article I’m going to show simple Github OAuth authorization in your web application using aioauth-client.
Starting from a scratch
Create main application script app.py
and install requirements into your virtual env
1 | $ mkvirtualenv -p python3 app |
and then create a simple endpoint. The simplest version of the server will look like this
1 | from aiohttp import web |
Now let’s register your new app on github and add /auth
route to your application. Click here and register your app to obtain client id
and client secret
values. Note that while developing you may need proxy github request to your application running at localhost but that can be easily bypassed with a help of ngrok. On the screenshot below you see tunnels such a values for ngrok tunnels to my local app.
Do not worry, when going to production you will change those to your own domain. Just add secrets to your application file and create additional endpoint for authorization
1 | GITHUB_CLIENT_ID = '<your-client-id>' |
Now visit /auth
endpoint in your browser and you’ll get redirected to github auth page and the you’ll see a token in console output. This token allows you to do authorized requests and obtain data you may be interested in defined by scope your request. We now can make a request using this token and retrieve some information about user like this
1 | ... |
and browser will render a page with data like login, id, email, etc. This has no much use though as long as we do not store this token anywhere in order for other routes to be able make same request too. Meet aiohttp-session
for the rescue
1 | $ pip install cryptography aiohttp_session |
The simplest way is to store our session data as an encrypted cookie and that will be shared between all our requests. Get this package configured first
1 | from aiohttp_session.cookie_storage import EncryptedCookieStorage |
As another helper utility we will create login_required
decorator requiring endpoint to pass authorization first or reuse existing info stored within our session.
1 | def login_required(fn): |
Note additional parameter redirect_uri
allowing us to continue browsing our web site starting from the last page visited not from the index one.
And below is a modified version of github_auth
function
1 | async def github_auth(request): |
We are following the same steps as previously but this time we store token
in our session and therefore no need to request it each time user hits the endpoint.
Finally decorate any of your endpoints as shown below and access your user info in a handy way.
1 |
|
Visiting /restricted
will show such you a message
Hello, bmwant in our restricted area!
Summary
I have covered only basic usage of the package for authorization but you should keep in mind that connecting other networks like Bitbucket, Facebook, Google, Twitter, VK, Yandex is as easy as adding singe endpoint to existing code. Next steps will be storing your user in Redis cache (and not making query to third party services on each request) and implementing /logout
route (just deleting a token from a session and redirecting to index page). At this point you should be good to go developing your application with simple authorization in place.