Getting invalid_scope when attempting to obtain a refresh token via the Google API
Asked Answered
H

3

17

I can't seem to be able to utilize the Google API with Oauth. What am I missing?

Error Message:

com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "invalid_scope",
  "error_description" : "Invalid oauth scope or ID token audience provided."
}

Java code:

private void printLabels() {

    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

    List<String> scopes = new ArrayList<>();
    scopes.add(GmailScopes.GMAIL_LABELS);

    GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("C:\\test\\credential.json"));
    credential.createScoped(scopes);
    credential.refreshToken();      // error happens here

    String appName = "VS";
    Gmail.Builder builder = new Gmail.Builder(httpTransport, jsonFactory, credential)
            .setApplicationName(appName);
    Gmail gmail = builder.build();

    Object o = gmail.users().labels().list("me").execute();
    System.out.println("o = " + o);
}

Google API Configuration:

  1. Logged in to https://console.developers.google.com/
  2. Created project
  3. Enabled Gmail API
  4. Created Service Account (assigned owner role)
  5. Download json credentials file
  6. Enabled OAuth consent screen - internal (not sure I need this since I only want to access my emails)
  7. Enabled service account domain wide delegation (not sure I need this either)
Hygrograph answered 25/2, 2020 at 18:27 Comment(5)
It's a bit unclear on what you're trying to do, and this code is incomplete. The docs say that refreshing a token is handled automatically.Solitary
Hello @ChristopherSchneider, thank you for your reply. I updated my question with additional code that I have been using. This is my first attempt at using the Google API so I am just aiming at printing labels. To your point, I tried to skip the refreshToken() call since Google would handle automatically but ended up getting the same error further down, when calling the execute(). Do you see anything else that I would be missing or doing wrong ?Hygrograph
I have th same issue with revolution/laravel-google-sheets, have you found the solution?Alfredalfreda
@Alfredalfreda you may add 'scopes' => [Google_Service_Sheets::DRIVE, Google_Service_Sheets::SPREADSHEETS], in your google configPrudie
@Prudie thks, I will test thisAlfredalfreda
B
17

In my case I was having that issue using Python default() to get the default credentials. It worked fine for the credentials loaded with gcloud auth application-default login or Kubernetes Workload Identity. But when using a Service Account file with GOOGLE_APPLICATION_CREDENTIALS I was having this issue when trying to call credentials.refresh(). I fixed the issue by explicitly providing the scopes parameter to default() function with the ['https://www.googleapis.com/auth/cloud-platform'] scope.

So I changed from this:

from google.auth import default

credentials, _ = default()

To this:

from google.auth import default

credentials, _ = default(scopes=['https://www.googleapis.com/auth/cloud-platform'])
Bimestrial answered 24/11, 2022 at 14:48 Comment(1)
THIS was the solution for me in python, though I still don't understand why scopes had to be added with the cloud-platform scope when I'm using the Cloud Runtime Configurator API.Brittnee
C
11

credential.createScoped(scopes)

Returns a copy of credential object with the given scope. You can verify this by credential.getServiceAccountScopes() and check if the scope is set.

Try assigning the value to credential object, like.

credential = credential.createScoped(scopes);
Chuppah answered 10/9, 2021 at 7:41 Comment(1)
From evening 9pm to early morning 4:20am, finally I read this answer. Initialising GoolgeCredentials with created scope is the trick 'credential = credential.createScoped(scopes);'. Thank you!Timbering
A
0

I don't know if you are having the same problem I had, but here was my issue and how I fixed it.

I am making an app and storing the credentials in a database. In order to use them I create an instance of google.oauth2.credentials.Credentials. I went back and forth between my database and this object using a dictionary. As scopes should be passed as lists and the google credentials are first stransformed into json and then a dict using the ast module, this meant that my scopes field was now of the form "['http://...']". When converting back, this introduced some extraneous characters, and it also isn't the correct format. I fixed this by modifying the value right before creating the new instance of the google credentials object. I am using python so it looks something like

creds_dict['scopes'] = [creds_dict['scopes'][2:-2]]

where creds_dict is the dictionary associated to an entry in my database.

This was sure a headache.

Adeline answered 9/6, 2024 at 23:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.