J'ai cherché pendant des heures une réponse à cette question, alors soyez indulgents avec moi!
J'utilise Apps Script pour me connecter à l'API Google Drive. J'ai créé un compte de service dans la console et collecté les informations d'identification pertinentes. J'ai le code suivant:
function test() { function getOAuthService(user) { var JSON = { "private_key": "-----BEGIN PRIVATE KEY-----\nMY KEY HERE\n", "client_email": "clientemail@clientemail.iam.gserviceaccount.com", "client_id": "11111111111111", "user_email": "myemail@myemail.com" }; return OAuth2.createService("Service Account") .setTokenUrl('https://accounts.google.com/o/oauth2/token') .setPrivateKey(JSON.private_key) .setIssuer(JSON.client_email) .setSubject(JSON.user_email) .setPropertyStore(PropertiesService.getScriptProperties()) .setParam('access_type', 'offline') .setScope('https://www.googleapis.com/auth/drive'); } function getUserFiles() { var service = getOAuthService(); service.reset(); var url = 'https://www.googleapis.com/drive/v2/files?pageSize=1'; var response = UrlFetchApp.fetch(url, { headers: { Authorization: 'Bearer ' + service.getAccessToken() }, muteHttpExceptions: true }); Logger.log(response.getContentText()); } function reset() { var service = getOAuthService(); service.reset(); } getUserFiles() }
J'ai également ajouté la bibliothèque OAuth2 dans le script.
Chaque fois que j'exécute cela, je rencontre l'erreur suivante: Erreur: accès non accordé ou expiré. (ligne 454, fichier «Service»)
Est-ce que quelqu'un a des idées?
Merci!
3 Réponses :
Que diriez-vous de la modification suivante?
return OAuth2.createService("Service Account") .setTokenUrl('https://accounts.google.com/o/oauth2/token') .setPrivateKey(JSON.private_key) .setIssuer(JSON.client_email) // .setSubject(JSON.user_email) // <--- Removed .setPropertyStore(PropertiesService.getScriptProperties()) .setParam('access_type', 'offline') .setScope('https://www.googleapis.com/auth/drive');
return OAuth2.createService("Service Account") .setTokenUrl('https://accounts.google.com/o/oauth2/token') .setPrivateKey(JSON.private_key) .setIssuer(JSON.client_email) .setSubject(JSON.user_email) .setPropertyStore(PropertiesService.getScriptProperties()) .setParam('access_type', 'offline') .setScope('https://www.googleapis.com/auth/drive');
À titre d'information supplémentaire, lorsque la liste des fichiers est récupérée par le compte de service, le Drive est différent de votre Google Drive de votre compte Google. Veuillez faire attention à cela. Si vous souhaitez récupérer la liste des fichiers de votre Google Drive, par exemple, lorsqu'un dossier de votre Google Drive est partagé avec l'adresse e-mail du compte de service, la liste des fichiers du dossier peut être récupérée par le compte de service.
D'après les commentaires d'Iamblichus. Réf et Réf
.setSubject
, mais ne fonctionnera pas si domaine- la délégation large n’est pas définie). Mais comme l'OP souhaitait accéder au Drive du compte de service et ne pas se faire passer pour un autre compte, il n'y avait aucune raison d'utiliser .setSubject
.
Merci pour votre réponse. Bien que l'OP n'ait pas clarifié sa situation sur la question, je pense qu'il serait approprié de clarifier un peu plus cela, pour d'autres personnes confrontées à ce même problème: le code d'origine aurait été correct si le compte de service avait obtenu un domaine -wide et l'OP souhaitaient utiliser la SA pour se faire passer pour un autre utilisateur du domaine (cela se fait via .setSubject
, mais ne fonctionnera pas si la délégation à l'échelle du domaine n'est pas définie).
Mais comme l'OP souhaitait accéder au Drive du compte de service et ne pas se faire passer pour un autre compte, il n'y avait aucune raison d'utiliser .setSubject
.
@Iamblichus Merci pour votre soutien constant. Je pourrais ajouter vos informations supplémentaires à la section Node. Je pense également que ce sera utile pour les autres utilisateurs. Merci beaucoup.
Vous pouvez utiliser Advanced Drive Service pour répertorier les fichiers. Vous n'avez pas besoin d'une bibliothèque OAuth ou même d'obtenir un jeton OAuth. Vous devrez activer le service Advanced Drive à partir du menu "Ressources" et l'option de menu "Services Google avancés".
function listFiles() { var file; var query = 'trashed = false'; var files; var pageToken; do { files = Drive.Files.list({ q: query, maxResults: 100, pageToken: pageToken }); if (files.items && files.items.length > 0) { for (var i = 0; i < files.items.length; i++) { file = files.items[i]; Logger.log('%s (ID: %s)', file.title, file.id); } } else { Logger.log('No files found.'); } pageToken = files.nextPageToken; } while (pageToken); }
La note à la fin de la réponse de Tanalike a fonctionné ici - mon problème n'était pas d'ajouter l'adresse e-mail de mon compte de service à Google Drive. J'ai remplacé user_email par mon e-mail de service (et partagé cette adresse e-mail dans un dossier dans Drive) et cela a parfaitement fonctionné. Merci de votre aide!
.setSubject
sert à emprunter l'identité d'autres comptes (ne fonctionnera que si le compte de service a reçu une autorisation à l'échelle du domaine ). Pour accéder au Drive du compte de service, cette méthode n'est pas nécessaire (et ne doit en fait pas être utilisée). De plus, je ne vois aucune raison d'utiliser service.reset();
, J'envisagerais de supprimer cette ligne.
avez-vous une "ligne 454"?
Je pense que l'op fait référence à cette ligne
var response = UrlFetchApp.fetch(url, { headers: {Authorization: 'Bearer ' + service.getAccessToken()}, muteHttpExceptions: true });
Je n'ai pas de ligne 454, je suppose que cela fait partie de l'API. Aucune suggestion?