You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NodeJS服务账户调用Google Drive API时遇404文件未找到错误

问题:NodeJS中使用服务账户调用Google Drive API返回404权限错误

我在NodeJS中使用服务账户通过文件ID调用Google Drive API的GET接口,请求始终失败,返回如下404错误(根据官方错误文档,该错误实际代表权限不足):

{
  "code": 404,
  "errors": [
    {
      "message": "File not found: XXX.",
      "domain": "global",
      "reason": "notFound",
      "location": "fileId",
      "locationType": "parameter"
    }
  ]
}

权限范围(Scope)

我测试过添加多个额外scope,但始终保留了https://www.googleapis.com/auth/drive:

const scopes = [
  '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',
];

服务账户(Service account)配置

  • 按照常规流程创建了服务账户,参考过多个官方及第三方资源
  • 已启用Google Drive API
  • 在Google Admin控制台启用了Domain-wide Delegation,并配置了上述相同的scope(也测试过不启用该选项的情况)

源代码尝试

官方NodeJS快速入门采用OAuth2弹窗授权,不符合无用户交互的机器对机器访问需求,我尝试了多种实现方式:

使用google-auth-library包

const { auth } = require('google-auth-library');

const client = auth.fromJSON({
  type: 'service_account',
  project_id: 'XXX',
  private_key_id: 'XXX',
  private_key: 'XXX',
  client_email: 'X@Y.iam.gserviceaccount.com',
  client_id: 'XXXX',
  auth_uri: 'https://accounts.google.com/o/oauth2/auth',
  token_uri: 'https://oauth2.googleapis.com/token',
  auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
  client_x509_cert_url:
    'https://www.googleapis.com/robot/v1/metadata/x509/X%40Y.iam.gserviceaccount.com',
});

const scopes = ['https://www.googleapis.com/auth/drive'];
client.scopes = scopes;
// 测试过supportsAllDrives设为true/false两种情况

const url = `https://www.googleapis.com/drive/v3/files/XXX?fields=name&supportsAllDrives=true`;
client.request({ url }).then(console.log).catch(console.error);

使用ts-google-drive包

import { TsGoogleDrive } from 'ts-google-drive';

const tsGoogleDrive = new TsGoogleDrive({
  credentials: {
    client_email: 'X@Y.iam.gserviceaccount.com',
    private_key: '',
  },
});

async function getSingleFile(fileId: string): Promise<void> {
  // 返回undefined表示请求出错
  const file = await tsGoogleDrive.getFile(fileId);
  console.log('file', file);
  if (file) {
    const isFolder = file.isFolder;
    console.log('isFolder', isFolder);
  }
}

getSingleFile('XXX');

使用googleapis包

const { google } = require('googleapis');

const auth = new google.auth.GoogleAuth({
  keyFile: 'service-account.json', // 文件路径正确
  scopes: [...], // 使用上述相同的scope
});

const drive = google.drive({ version: 'v3', auth });

const driveResponse = await drive.files.list({
  fields: '*',
});

const file = await drive.files.get({
  fileId: 'XXX',
  fields: 'name',
  supportsAllDrives: true,
});

console.log(file); // 此处报错!

使用googleapis搭配jwtClient

const google = require('googleapis');
const key = require('./service-account.json');

const scopes = [...]; // 使用上述相同的scope

const jwtClient = new google.google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  scopes,
  null,
);

jwtClient.authorize(async (authErr) => {
  if (authErr) {
    console.log(authErr); // 此处无错误
    return;
  }

  const drive = google.google.drive({ version: 'v3', auth: jwtClient });

  console.log('jwtClient.getCredentials()', jwtClient.getCredentials());
  console.log('jwtClient.apiKey', jwtClient.apiKey);
  console.log('jwtClient.credentials', jwtClient.credentials);
  console.log('jwtClient.gtoken', jwtClient.gtoken);

  // 实际请求API时出错
  const file = await drive.files.get({
    fileId: 'XXX',
    fields: 'name',
    supportsAllDrives: true,
  });

  console.log(file);
});

./service-account.json文件结构:

{
  "type": "service_account",
  "project_id": "X",
  "private_key_id": "XXXX",
  "client_email": "X@Y.iam.gserviceaccount.com",
  "client_id": "XXX",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/X%Y.iam.gserviceaccount.com"
}

Google Drive资源权限

我需要访问公司内部Google Drive文件,在为服务账户分配权限时遇到问题:尝试向服务账户共享文件夹/驱动器失败。另外,即使是已单独共享给服务账户的文件(位于“与我共享”中)也无法访问,但公司Drive中的所有公开文件均可正常访问。

期望结果

实现无需用户交互,通过服务账户访问公司Drive中“与我共享”和“共享驱动器”内的文件。

内容的提问来源于stack exchange,提问作者michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:15:40