我正在尝试编写一个客户端 JS 脚本,该脚本将从我的 gDrive 中获取图像以使用服务帐户显示在网站上。我创建了服务帐户并为该项目添加并启用了 google Drive API。但是当我运行脚本时,出现 403 错误:超出了未经身份验证使用的每日限制。继续使用需要注册。我认为这可能与权限或范围有关?我看过其他几个堆栈溢出,但似乎无法弄清楚。
Getting a 403 - Forbidden for Google Service Account
Google Drive service account returns 403 usageLimits
其中一些提到添加 Angular 色或范围,但我无法弄清楚如何添加它们或我需要添加哪些。 GSuite 帐户是强制性的吗?听起来我需要进入 GSuite 管理控制台来添加范围?我不想注册一个帐户,因为它不是免费的。任何帮助,将不胜感激。我的代码如下所示:
function gDrive() {
function init(callback) {
authorizeClient(getJWT()).then(function(token) {
loadClient(token, callback);
});
}
/* Retrieve a signed JWT */
function getJWT() {
// Prepare header, payload, and key
let oHeader = {
"alg": "RS256",
"typ": "JWT"
};
let sHeader = JSON.stringify(oHeader);
let oPayload = {
"iss": "SERVICE ACCOUNT EMAIL",
"sub": "SERVICE ACCOUNT EMAIL",
"aud": "https://www.googleapis.com/oauth2/v3/token",
"iat": KJUR.jws.IntDate.getNow(),
"exp": KJUR.jws.IntDate.get("now + 1hour"),
"scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive.photos.readonly https://www.googleapis.com/auth/drive.readonly"
};
let sPayload = JSON.stringify(oPayload);
let privKey = "-----BEGIN PRIVATE KEY-----BLAH BLAH BLAH\n-----END PRIVATE KEY-----\n";
// Sign JWT
return signedJWS = KJUR.jws.JWS.sign(null, sHeader, sPayload, privKey);
}
/* Http POST to Google Auth api */
function authorizeClient(JWS) {
// Request access token
const url = "https://www.googleapis.com/oauth2/v3/token";
let encodedData = "";
let encodedDataPairs = [];
encodedDataPairs.push(encodeURIComponent("grant_type") + '=' + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"));
encodedDataPairs.push(encodeURIComponent("assertion") + '=' + encodeURIComponent(JWS));
encodedData = encodedDataPairs.join('&').replace(/%20/g, '+');
const params = {
headers: {"content-type":"application/x-www-form-urlencoded"},
body: encodedData,
method: "POST"
};
return fetch(url, params).then(accessTokenSucces).then(returnToken).catch(accessTokenFailed);
}
function accessTokenSucces(data) {
console.log("Retrieved access token");
return data.json();
}
function returnToken(resp) {
return resp.access_token;
}
function accessTokenFailed(error) {
console.log("Requesting access token failed: " + error);
}
function loadClient(accessToken, callback) {
gapi.load('client', function() {
console.log("loading client");
gapi.client.setToken(accessToken);
console.log("set access token");
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/drive/v3/rest").then(clientLoadSuccessful).then(callback).catch(clientLoadFailed);
})
}
function clientLoadSuccessful() {
console.log("Client loaded");
return Promise.resolve();
}
function clientLoadFailed(error) {
console.log("Loading Client failed: " + error);
return Promise.reject();
}
function fetchAllImages(fileName, chapter, callback) {
console.log("fetching images");
let initialRequest = gapi.client.drive.files.list({"q": "mimeType contains \"image\" and name contains '"
+ fileName + "_ch" + chapter + "'"});
retrievePageOfFiles(initialRequest, [], fileName, chapter);
function retrievePageOfFiles(request, result) {
request.execute(function(resp) {
result = result.concat(resp.files);
let nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = gapi.client.drive.files.list({
"pageToken": nextPageToken,
"q": "mimeType contains \"image\" and name contains '" + fileName + "_ch" + chapter + "'"
});
retrievePageOfFiles(request, result);
} else {
console.log("Images retrieved");
callback(result);
}
}).catch(function(err) {
console.log("Could not retrieve images: " + err);
});
}
}
return {
init: init,
fetchAllImages: fetchAllImages
};
}
gDrive().init(runApp);
function runApp() {
console.log("Running App");
gDrive().fetchAllImages("FILENAME", "1", imageCallback);
}
function imageCallback(data) {
console.log("Images Retrieved!");
console.log(data);
}
最佳答案
- 当您的脚本运行时,
未验证使用的每日限制已超出错误。继续使用需要注册。
发生。 - 您想消除这个错误。
如果我的理解是正确的,这个修改怎么样?我认为可以使用您的脚本检索到的访问 token 。所以请按如下方式修改您的脚本。
来自:
gapi.client.setToken(accessToken);
收件人:
gapi.client.setToken({access_token: accessToken});
引用:
如果这不是您问题的直接解决方案,我深表歉意。
关于javascript - 如何使用服务帐户和 Google Drive API 解决 403 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59295318/