Search code examples
pythongoogle-drive-apigoogle-oauthgoogle-api-python-client

When does a Credentials object become invalidated?


I am playing with a Python script that is based on https://developers.google.com/drive/v3/web/quickstart/python and it works fine. I can upload simple text files to my Drive account.

The code on that page is as follows:

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive API Python Quickstart'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'drive-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

Suppose that the script is executed once, resulting in 'drive-python-quickstart.json' file being saved with something like this (X's replacing sensitive information of course):

{"_module": "oauth2client.client",
 "scopes": ["https://www.googleapis.com/auth/drive.file"],
 "token_expiry": "2016-11-13T07:15:15Z",
 "id_token": null,
 "access_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
 "token_uri": "https://accounts.google.com/o/oauth2/token",
 "invalid": false,
 "token_response": {"access_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                    "token_type": "Bearer",
                    "expires_in": 3600,
                    "refresh_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"},
 "client_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com",
 "token_info_uri": "https://www.googleapis.com/oauth2/v3/tokeninfo",
 "client_secret": "XXXXXXXXXXXXXXXXXXXXXXXX",
 "revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
 "_class": "OAuth2Credentials",
 "refresh_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
 "user_agent": null}                                  

Let's suppose that the 'drive-python-quickstart.json' file is always existing and both readable and writable. Suppose some time passes, and the script executes again at some time after the time given by the "token_expiry" key in that JSON value. Is it expected that something detects that the time has expired on the Credentials object, forcing the credentials object to switch into an invalid state, which means that credentials.invalid then becomes True? Or is it the case that the existence of the "refresh_token" field implies that the something in the API will automatically update the 'drive-python-quickstart.json' file automatically such that credentials.invalid always returns True?


Solution

  • The Google python client library will refresh the access token as needed as long as your refresh token is good. To be clear, the client library is used to access the API. The API has no control over your authentication. It expects you, or rather the client library, to send it the information it requires in order for it to work.

    Top Tip: Refresh tokens that aren't used for six months will also expire, so I recommend you run your script at least once every six months.