Die Google Sheets-API gibt bei Verwendung des Serverschlüssels "Der Anrufer hat keine Berechtigung" zurück


89

Ich habe im API-Manager einen Serverschlüssel generiert und versucht, Folgendes auf meinem Mac auszuführen:

curl 'https://sheets.googleapis.com/v4/spreadsheets/MySheetID?ranges=A1:B5&key=TheServerKeyIGeneratedInAPIManager'

Aber das ist es, was es zurückgibt:

{
 "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }
}

Was mache ich hier falsch?


4
Der Schlüssel ist für den Zugriff auf öffentliche Daten. Für Ihre Arbeit ist ein authentifizierter Zugriff erforderlich.
DaImTo

In den meisten Fällen gibt es ein Problem mit den Bereichen. Bitte überprüfen Sie, welche Bereiche für das Skript erforderlich sind.
dpkrai96

Antworten:


119

Um dieses Problem zu lösen, versuchen Sie:

  1. Erstellen Sie ein Dienstkonto: https://console.developers.google.com/iam-admin/serviceaccounts/
  2. Erstellen Sie in den Optionen einen Schlüssel: Dieser Schlüssel ist Ihre übliche client_secret.json - verwenden Sie ihn auf die gleiche Weise
  3. Machen Sie den Rollenbesitzer für das Dienstkonto (Mitgliedsname = Dienstkonto-ID = Dienstkonto-E-Mail-Adresse: thomasapp@appname-201813.iam.gserviceaccount.com
  4. Kopieren Sie die E-Mail-Adresse Ihres Dienstkontos = Dienstkonto-ID
  5. Gehen Sie einfach in Ihrem Browser zu dem Google-Blatt, mit dem Sie interagieren möchten
  6. Gehen Sie zu TEILEN oben rechts auf Ihrem Bildschirm
  7. Gehen Sie zu den erweiterten Einstellungen und teilen Sie sie mit der E-Mail-Adresse Ihres Dienstkontos, z. B.: Thomasapp@appname-201813.iam.gserviceaccount.com

Es hat bei mir funktioniert :)


1
das hat bei mir funktioniert. Übrigens: Gehen Sie in Google Cloud Admin zu ... Projekt> IAM & Admin> Dienstkonten .... Wenn Sie Dienstkonten eingerichtet haben, wird für jedes Dienstkonto eine spezielle E-Mail angezeigt. Stellen Sie sicher, dass Sie auch die Google Sheets-API aktiviert haben. Im wahrsten Sinne des Wortes teilen Sie einfach die E-Mail-Adresse des Dienstkontos über die Schaltfläche "Teilen" auf dem Google-Blatt mit.
Jason F

1
Ja ... Der Schlüssel ist, das Dokument einfach mit der E-Mail-
Adresse

2
Der Schlüssel json unterscheidet sich stark von den Anmeldeinformationen json, die ich aus der Java-Kurzanleitung (für die Sheets-API) erhalten habe. Wie implementiere ich es?
Kardinal - Wiedereinsetzung Monica

2
Wie nutzt du das Kundengeheimnis? Können Sie stattdessen einen API-Schlüssel mit einem Dienstkonto erstellen?
Stephen Phillips

42

Ich weiß, dass es etwas spät ist zu antworten, aber für andere Menschen, die mit dem gleichen Problem zu kämpfen haben. Ändern Sie
einfach die Berechtigung des Arbeitsblatts auf Ihrem Laufwerk in "Öffentlich" , damit Sie ohne Authentifizierung über API-Aufrufe darauf zugreifen können.

So ändern Sie den Zugriff:

  1. Blatt in Google Drive öffnen
  2. Klicken Sie oben rechts auf Freigeben
  3. Klicken Sie unten im Eingabeaufforderungsfenster auf Erweitert
  4. Ändern Sie die Berechtigung in öffentlich oder Personen mit Link (keine Anmeldung erforderlich)

Senden Sie eine API-Anfrage, um Daten von Blättern ohne Authentifizierung abzurufen.

Hinweis: Wenn das Blatt vertrauliche Daten enthält, ist es nicht sicher, sie öffentlich zu machen, sondern mit authentifiziertem Zugriff.


36
Sie können dieses Blatt auch mit einer bestimmten E-Mail-Adresse teilen. E-Mail Ihres Dienstkontos (Projekts). "client_email": "XXXXX@northern-gasket-XXXX.iam.gserviceaccount.com", Dies ermöglicht den Zugriff auf das Blatt über Ihr Skript.
Kishan Patel

4
Dank bro. Es gibt keine schriftlichen Unterlagen, wie Sie sie erwähnt haben.
Maulik Dodia

1
Einverstanden @MaulikDodia. Google API-Dokumente sagen es hier , aber es ist nicht klar für Leute, die nur die API verwenden möchten, um Daten auf einer öffentlichen Website anzuzeigen. Ich bin gerade dabei, eine Anleitung zu all dem zu schreiben. Ich schicke dir eine DM davon, wenn ich fertig bin.
Edward

Vielen Dank friend @ user3411192
Maulik Dodia

27

Achten Sie unbedingt auf den Kommentar von @ KishanPatel:

Sie können dieses Blatt auch mit einer bestimmten E-Mail-Adresse teilen. E-Mail Ihres Dienstkontos (Projekts). "client_email": "XXXXX@northern-gasket-XXXX.iam.gserviceaccount.com", Dies ermöglicht den Zugriff auf das Blatt über Ihr Skript.


4

Am einfachsten ist es, das Problem mit gcloud cli zu beheben. Weitere Dokumente finden Sie hier https://cloud.google.com/pubsub/docs/quickstart-cli#before-you-begin

gcloud installieren

sudo apt-get install google-cloud-sdk

Dann ruf an

gcloud init

Überprüfen Sie dann Ihr aktives Projekt und Ihre Anmeldeinformationen

gcloud config configurations list

Wenn dies nicht in Ordnung ist, stellen Sie sicher, dass Sie mit dem richtigen Konto authentifiziert sind:

gcloud auth list
* account 1
  account 2

Wechseln Sie zum Projektkonto, wenn nicht:

gcloud config set account `ACCOUNT`

Je nach Konto ist die Projektliste unterschiedlich:

gcloud projects list

- project 1
- project 2...

Zum beabsichtigten Projekt wechseln:

gcloud config set project `PROJECT NAME`

Erstellen Sie dann Standardanmeldeinformationen für Anwendungen mit gcloud auth application-default login, und Google Cloud erkennt diese Anmeldeinformationen automatisch.


0

Meine 10 Cent ... Ein einfaches Beispiel, um das Blatt mit Java zu lesen .

    private Credential getCredentials() throws IOException {
            final InputStream accessKey = new ByteArrayInputStream("<credential json>");
            final GoogleCredential credential = GoogleCredential.fromStream(accessKey)
                    .createScoped(Collections.singleton(SheetsScopes.SPREADSHEETS_READONLY));
            return credential;
        }

    private HttpTransport httpTransport() {
            try {
                return GoogleNetHttpTransport.newTrustedTransport();
            } catch (GeneralSecurityException | IOException e) {
                throw new SpreadSheetServiceException(e);
            }
        }


    Sheets service = new Sheets.Builder(httpTransport(), JSON_FACTORY, getCredentials())
                    .setApplicationName("app-name")
                    .build();
            ValueRange response = service.spreadsheets().values()
                    .get("<spread_sheet_id>", "A1:A")
                    .execute();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.