L'API Google Sheets renvoie "L'appelant n'a pas l'autorisation" lors de l'utilisation de la clé de serveur


89

J'ai généré une clé de serveur dans le gestionnaire d'API et tenté d'exécuter ce qui suit sur mon Mac:

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

Mais c'est ce qu'il renvoie:

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

Qu'est-ce que je fais de mal ici?


4
La clé est d'accéder aux données publiques, ce que vous faites nécessite un accès authentifié.
DaImTo

Dans la plupart des cas, il y a un problème de portée. Veuillez vérifier et vérifier les portées requises par le script.
dpkrai96

Réponses:


119

Pour résoudre ce problème, essayez de:

  1. Créez un compte de service: https://console.developers.google.com/iam-admin/serviceaccounts/
  2. Dans les options, créez une clé: cette clé est votre client_secret.json habituel - utilisez-la de la même manière
  3. Définissez le rôle comme propriétaire du compte de service (Nom du membre = ID du compte de service = e-mail du compte de service, ex: thomasapp@appname-201813.iam.gserviceaccount.com
  4. Copiez l'adresse e-mail de votre compte de service = ID de compte de service
  5. Accédez simplement à la feuille Google avec laquelle vous souhaitez interagir dans votre navigateur
  6. Accédez à PARTAGER en haut à droite de votre écran
  7. Accédez aux paramètres avancés et partagez-le avec l'adresse e-mail de votre compte de service, ex: thomasapp@appname-201813.iam.gserviceaccount.com

Cela a fonctionné pour moi :)


1
cela a fonctionné pour moi. au fait: dans Google Cloud Admin, accédez à ... projet> IAM et administration> Comptes de service .... Si vous avez configuré des comptes de service, vous verrez un e-mail spécial pour chaque compte de service respectif. Assurez-vous d'avoir également activé l'API Google Sheets. Littéralement, il vous suffit de partager l'adresse e-mail du compte de service à partir du bouton "Partager" de la feuille Google.
Jason F

1
oui ... la clé est de simplement partager le document avec l'e-mail du compte de service ....
user1102171

2
La clé json est très différente des informations d'identification json que j'ai obtenues dans le guide de démarrage rapide Java (pour l'API Sheets). Comment le mettre en œuvre?
Cardinal - Réintégrer Monica le

2
Comment utilisez-vous le secret client? Pouvez-vous créer une clé API avec un compte de service à la place?
Stephen Phillips

42

Je sais qu'il est un peu tard pour répondre, mais pour d'autres personnes aux prises avec le même problème. Changez
simplement l'autorisation de la feuille en public sur votre lecteur afin qu'elle soit accessible sans authentification via des appels API.

Pour modifier l'accès:

  1. Ouvrir la feuille dans Google Drive
  2. Dans le coin supérieur droit, cliquez sur partager
  3. Au bas de la fenêtre d'invite, cliquez sur avancé
  4. Modifier l'autorisation en public ou personnes avec lien (aucune connexion requise)

Envoyez une requête API pour récupérer les données des feuilles sans authentification.

Remarque: si la feuille contient des données sensibles, il n'est pas sûr de la rendre publique et de le faire plutôt avec un accès authentifié.


36
En outre, vous pouvez partager cette feuille avec un e-mail spécifique Ex. l'email de votre compte de service (projet). "client_email": "XXXXX@northern-gasket-XXXX.iam.gserviceaccount.com", Cela permettra d'accéder à la feuille par votre script.
Kishan Patel le

4
Merci mec. Il n'y a pas de choses écrites dans la documentation que vous avez mentionnées.
Maulik Dodia

1
D'accord @MaulikDodia. La documentation de l'API Google le dit ici , mais ce n'est pas clair pour les personnes qui souhaitent simplement utiliser l'API pour afficher des données sur un site Web public. Je suis en train d'écrire un guide sur tout cela. Je vous en enverrai un DM quand j'aurai terminé.
Edward

Merci beaucoup mon ami @ user3411192
Maulik Dodia

27

Assurez-vous de faire attention au commentaire de @ KishanPatel:

En outre, vous pouvez partager cette feuille avec un e-mail spécifique Ex. l'email de votre compte de service (projet). "client_email": "XXXXX@northern-gasket-XXXX.iam.gserviceaccount.com", Cela permettra d'accéder à la feuille par votre script.


4

Le moyen le plus simple est de résoudre le problème à l'aide de gcloud cli. Plus de documentation ici https://cloud.google.com/pubsub/docs/quickstart-cli#before-you-begin

installer gcloud

sudo apt-get install google-cloud-sdk

puis appelle

gcloud init

puis vérifiez votre projet actif et vos informations d'identification

gcloud config configurations list

Si ce n'est pas le cas, assurez-vous que vous êtes authentifié avec le bon compte:

gcloud auth list
* account 1
  account 2

Si ce n'est pas le cas, passez au compte du projet:

gcloud config set account `ACCOUNT`

Selon le compte, la liste des projets sera différente:

gcloud projects list

- project 1
- project 2...

Passer au projet prévu:

gcloud config set project `PROJECT NAME`

Créez ensuite les informations d'identification par défaut de l'application avec gcloud auth application-default login, puis google-cloud détectera automatiquement ces informations d'identification.


0

Mes 10 cents ... Un exemple simple pour lire la feuille en Java .

    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();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.