So as I’m attempting to build this fireprotocol site as a Flask application, I’m following the great Grinberg’s Flask tutorial and I ran into a problem when authenticating my users, I spent a few days reading up on Google’s Python library and Flask docs.
This is a quick and simple demonstration of how to integrate Google’s OAuth2.0 API into a Flask application using the google-api-python-client library. So you’re going to need to install and import Google’s library, on top of all other Flask and Python libraries you might need:
$ pip install --upgrade google-api-python-client
Then I’ve created
fpapp/oauth.py file to write a login class called
GoogleLogin that I will use for easier management:
The __init__ method initializes our class by creating a client object, using the client_secrets.json file that you should’ve obtained from setting up your OAuth2.0 application credentials at Google’s console, the scope parameter will determine what information we are going to receive from the API, in my case I’m only aiming for the name, username and email, you can play and try different scopes using the Google API Explorer. The redirect_uri needs to point to the view (/oauth2callback) of your application that will handle the response.
step1 method generates the URL from the client object previously created, and then we redirect the user to Google’s auth_uri .
step2 method stores the authorization code query string parameter from Google in a variable called auth_code, we then use this code to exchange it for an access token, this is done by flow.step2_exchange(self.auth_code) , which we use to store in the flask.session object under the credentials key.
userinfo method uses the credentials object to apply an access token to the Http object, we then use the authorized Http object to make the request using the imported discovery class, the arguments can vary depending on the API, in this case, it is going to be ‘oauth2’ and ‘v2’. Then simply execute the request, the response is going to be an object built from the JSON response sent by Google’s API.
Time to put this into play, and I simply have an index.html file with an href link pointing to
/oauth2callback which users can click to authenticate, let’s take a look at the important parts of
At this point, if we were to go to the application, the index function will check to see if credentials is contained in the session object, this object is also a dictionary with key and value pairs of session variables, one of these being the ‘credentials’ key. If the user hasn’t logged in, it will present the index.html with a login link for the user to click on.
When the user is prompted to the /oauth2callback, we will check to see if the code query string parameter returned by step1 method contains the word ‘code’ in it, if it doesn’t, this means the user denied access and we will attempt to get access again by calling step1, if it does contain the word ‘code’, this means the user granted access and we proceed to exchange the code for a token, to then place the converted json into the flask.session object variable ‘credentials’ (this is all happening inside the step2 method)
After we are done here, we send back to the url_for(‘index’) page, only this time ‘credentials’ is going to be in the session object and we proceed to call userinfo method to call the Google’s API with the discovery.build function that we created inside userinfo .
We can then return to the screen the name and email of the person who authenticated by calling the ‘name’ and ’email key values of userinfor .