9

This function is to get authenticated service from Google. After

        API_SERVICE_NAME = 'youtubereporting'
        API_VERSION = 'v1'
        CLIENT_SECRETS_FILE = "client_secret_929791903032-hpdm8djidqd8o5nqg2gk66efau34ea6q.apps.googleusercontent.com.json"
        SCOPES = ['https://www.googleapis.com/auth/yt-analytics-monetary.readonly']
        def get_authenticated_service():
            flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
            credentials = flow.run_local_server()
            return build(API_SERVICE_NAME, API_VERSION, credentials=credentials)

But I want to use Refresh Token to automatically authenticate without opening a browser. Therefore add some codes into the function above to save Refresh Token:

def get_authenticated_service():
    flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
    credentials = flow.run_local_server()
    with open('refresh.token', 'w+') as f:
        f.write(credentials._refresh_token)
    print('Refresh Token:', credentials._refresh_token)
    print('Saved Refresh Token to file: refresh.token')
    return build(API_SERVICE_NAME, API_VERSION, credentials=credentials)

Okay, so after having the Refresh Token, How to use it? I tried to replace the refresh token ="ABCDEF456" but it does not work

def get_authenticated_service():
    return build(API_SERVICE_NAME, API_VERSION, credentials="ABCDEF456")
Prisoner
  • 49,922
  • 7
  • 53
  • 105
Analytics POPSWW
  • 255
  • 2
  • 4
  • 8
  • I don't understand what you mean by `I tried to replace the refresh token ="ABCDEF456" but it does not work` – John Hanley Jan 23 '19 at 07:30
  • What is API_SERVICE_NAME and API_VERSION? – John Hanley Jan 23 '19 at 07:31
  • @JohnHanley What I mean is after having the refresh token right? Then I read the refresh token file and then paste the value (for example: `ABCDEF456`) directly – Analytics POPSWW Jan 23 '19 at 07:43
  • I added API_SERVICE_NAME and API_VERSION! – Analytics POPSWW Jan 23 '19 at 07:44
  • Maybe the way that I pasted directly the refresh token into `build` function is wrong. That is why I ask this question. How to use Refresh Token? – Analytics POPSWW Jan 23 '19 at 07:47
  • Why are you pasting it. Just use the `cred._refresh_token` variable or read it from the file that you saved it. Note: You only use the Refresh Token to refresh the Access Token and ID Token. You don't use it in API calls. For that you use the Access Token. – John Hanley Jan 23 '19 at 07:50
  • In my answer I show you how to use the Refresh Token to get a new Access Token. In your build() call you use the Access Token to create new `credentials`. – John Hanley Jan 23 '19 at 07:52

1 Answers1

10

To refresh an Access Token, you call the Google OAuth endpoint passing in three parameters:

  • Client ID
  • Client Secret
  • Refresh Token

This can be done very simply with a simple HTTP POST request.

Here is an example using curl:

set REFRESH_TOKEN=REPLACE_WITH_REFRESH_TOKEN
 
curl ^
--data client_id=%CLIENT_ID% ^
--data client_secret=%CLIENT_SECRET% ^
--data grant_type=refresh_token ^
--data refresh_token=%REFRESH_TOKEN% ^
https://oauth2.googleapis.com/token

In Python using the requests library:

// Call refreshToken which creates a new Access Token
access_token = refreshToken(client_id, client_secret, refresh_token)

// Pass the new Access Token to Credentials() to create new credentials
credentials = google.oauth2.credentials.Credentials(access_token)

// This function creates a new Access Token using the Refresh Token
// and also refreshes the ID Token (see comment below).
def refreshToken(client_id, client_secret, refresh_token):
        params = {
                "grant_type": "refresh_token",
                "client_id": client_id,
                "client_secret": client_secret,
                "refresh_token": refresh_token
        }

        authorization_url = "https://oauth2.googleapis.com/token"

        r = requests.post(authorization_url, data=params)

        if r.ok:
                return r.json()['access_token']
        else:
                return None

Note: This code will also return a refreshed ID Token if originally requested during the authorization request.

Atharva
  • 6,711
  • 5
  • 31
  • 39
John Hanley
  • 74,467
  • 6
  • 95
  • 159
  • How to import `requests`? – Analytics POPSWW Jan 23 '19 at 09:19
  • Oh I imported! but the code returned nothing – Analytics POPSWW Jan 23 '19 at 09:28
  • this does not work and fails with The request is missing a valid API key – Ulysse Mizrahi Jun 23 '20 at 20:34
  • @UlysseMizrahi - API Keys and OAuth Tokens are different types of authorization. Create a new question showing how you created the tokens and the exact error message. – John Hanley Jun 23 '20 at 23:04
  • @Analytics POPSWW were you able to resolve your issue of not opening up the browser to authorize access to the GDrive files ? As I am stuck on a similar issue . Would be great if you could please share the steps to resolve it. I am having a oAuth2 client_secret.json which I am using to authorize and list files in the drive, I am then using the credentials.json file from service account to read the content. However, I would like to automate it without the need to authorize manually, and run the script from AWS EC2 instance. – Satya Mar 17 '21 at 19:14