John R Perry
John R Perry

Reputation: 4192

How to authorize an app with Google in Django on a live site

I am working with the Google Calendar API, but this would be applicable to any of their APIs.

I followed the quickstart example that they provide, and in a local environment, this works great. The main issue that I'm facing is that in a local environment, the code they provide is setup to automatically open a URL to authorize the application once authorization becomes necessary. This isn't the case in a live environment, and it has to do with this section of the code:

flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
creds = flow.run_local_server(port=0)

But, I don't quite understand what I should be calling in place.


Here's the full code of what they provide:

from __future__ import print_function
import datetime
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']

def main():
    """Shows basic usage of the Google Calendar API.
    Prints the start and name of the next 10 events on the user's calendar.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('calendar', 'v3', credentials=creds)

    # Call the Calendar API
    now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
    print('Getting the upcoming 10 events')
    events_result = service.events().list(calendarId='primary', timeMin=now,
                                        maxResults=10, singleEvents=True,
                                        orderBy='startTime').execute()
    events = events_result.get('items', [])

    if not events:
        print('No upcoming events found.')
    for event in events:
        start = event['start'].get('dateTime', event['start'].get('date'))
        print(start, event['summary'])

if __name__ == '__main__':
    main()

Upvotes: 3

Views: 3053

Answers (1)

John R Perry
John R Perry

Reputation: 4192

Explanation:

The example that Google provides on that page should actually work in a live environment. The area that I believe you are getting stuck on is the credential file that Google tells you to download after you enable the API.

Assuming you're using the credential file that can be downloaded after the API is enabled, the credential file will look like this:

{
  "installed": {
    "client_id": "<CLIENT_ID>",
    "project_id": "<PROJECT_ID>",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "<CLIENT_SECRET>",
    "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]
  }
}

The installed property is telling your program that this is an installed app on a local environment which isn't what you want.


Solution:

  1. Go into your project's credentials
  2. Click, "Create Credentials" and then click "OAuth client ID"
  3. On the next page, select "Web application" and add your redirect URIs (i.e. the url that you want Google to take the user after they have been authenticated)
  4. Click "Create"
  5. You'll be taken back to the main credentials page and you'll see your new credentials under "OAuth 2.0 client IDs". Click the link of the newly created credentials.
  6. Now that you're in the settings of your credentials page, you can now click, "DOWNLOAD JSON"

Assuming everything worked as expected, you should now have a json file that contains something like this:

{
  "web": {
    "client_id": "<CLIENT_ID>",
    "project_id": "<PROJECT_ID>",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "<CLIENT_SECRET>",
    "redirect_uris": [
      "<YOUR_REDIRECT_URIS>"
    ]
  }
}

Upvotes: 5

Related Questions