Google APIs OAuth in Django
— Django, Python, Google APIs — 1 min read
Making an authentication system with google sign-in is a relatively simpler task to do. It can be easily done using some librariers or plugins. But the problem comes when we need to access Google APIs of our users such as Google Calendar, Gmail, Drive etc. The main problem is getting the user tokens and storing them. So, that our application can access the Google APIs of the user once they've granted the access and not asking them to authenticate again and again.
So, here is how you can integrate Google OAuth with your Django application and retrieve, store the user tokens. Which can be used to create authenticated requests to Google APIs through google-api-python-client.
Objective
In this article, I am going to show you how you can integrate Google OAuth with your Django application and store the user tokens for future use, accessing the Upcoming Events in the user's Google Calendar using the stored credentials.
Prerequisites
I'm going to assume that you've already created a project in Google API Console, enabled the Google Calendar API for your project, setup an OAuth consent screen and you have a client_id.json file.
I'm also assuming that you have already initialized a django appliciation.
Let's Start
First of all you need to install google-apis-oauth-django to setup oauth and google-api-python-client to access Google APIs using the following command.
1pip install google-apis-oauth-django google-api-python-client
First of all create a "Sign In With Google" button that redirects users to an url say google_oauth/redirect/. First you need to create a view for redirecting users.
1import os2import google_apis_oauth3
4from django.shortcuts import HttpResponseRedirect5
6# The url where the google oauth should redirect7# after a successful login.8REDIRECT_URI = 'http://localhost:8000/google_oauth/callback/'9
10# Authorization scopes required11SCOPES = ['https://www.googleapis.com/auth/calendar']12
13# Path of the "client_id.json" file14JSON_FILEPATH = os.path.join(os.getcwd(), 'client_id.json')15
16def RedirectOauthView(request):17 oauth_url = google_apis_oauth.get_authorization_url(18 JSON_FILEPATH, SCOPES, REDIRECT_URI)19 return HttpResponseRedirect(oauth_url)
Now you need to assign an URL to this view.
1urlpatterns = [2 ...,3 path('google_oauth/redirect/', RedirectOauthView)4]
Now when a user clicks on that "Sign In With Google" button they would be redirected to a google oauth screen. After a successful login they would be redirected to the REDIRECT_URI
that we have specified above i.e. google_oauth/callback/.
So, we need to write a view for that as well. In that view we can now successfully retreive the user credentials as they are successfully authenticated by doing something like this.
1def CallbackView(request):2 try:3 # Get user credentials4 credentials = google_apis_oauth.get_crendentials_from_callback(5 request,6 JSON_FILEPATH,7 SCOPES,8 REDIRECT_URI9 )10
11 # Stringify credentials for storing them in the DB12 stringified_token = google_apis_oauth.stringify_credentials(13 credentials)14
15 # Store the credentials safely in the DB16 ...17
18 # Now that you have stored the user credentials you19 # can redirect user to your main application.20 ...21 except exceptions.InvalidLoginException:22 # This exception is raised when there is an inavlid23 # request to this callback uri.
Again, we'll need to assign an URL to this view.
1urlpatterns = [2 ...,3 path('google_oauth/callback/', CallbackView)4]
Now, as you have the user's credentials. You can access the Google APIs by the following method.
1import google_apis_oauth2from googleapiclient.discovery import build3
4# Load the stored credentials in a variable say 'stringified_token5
6# Load the credentials object using the stringified token.7creds, refreshed = google_apis_oauth.load_credentials(stringified_token)8
9# Using credentials to access Upcoming Events10service = build('calendar', 'v3', credentials=creds)11now = datetime.datetime.utcnow().isoformat() + 'Z'12print('Getting the upcoming 10 events')13events_result = service.events().list(14 calendarId='primary', timeMin=now,15 maxResults=10, singleEvents=True,16 orderBy='startTime').execute()17events = events_result.get('items', [])18
19if not events:20 print('No upcoming events found.')21for event in events:22 start = event['start'].get('dateTime', event['start'].get('date'))23 print(start, event['summary'])
That's it! Similarly you can use these credentials to access other Google APIs as well.