【问题标题】:Getting 403 from google drive api从 google drive api 获取 403
【发布时间】:2019-05-06 14:00:34
【问题描述】:

我正在尝试使用node client 访问谷歌驱动器。这将在后台进程中的服务器上运行,无需用户参与。在准备过程中,我做了以下工作:

  • 创建了服务帐号
  • 在我正在访问其驱动器的帐户上启用 Drive API access
  • 与服务帐户共享驱动器中的特定文件夹(下面称为MyFolder)。

我能够成功验证为服务帐户并列出目录中的文件。但是,我无法下载任何文件。当我尝试时,我显然收到了 403 错误。它有点隐藏在错误消息中,但这似乎是问题所在。这是我的代码:

const fs = require('fs');
const { google } = require('googleapis');
const auth = require('./service-creds.json');

(async () => {
    let jwtClient = new google.auth.JWT(auth.client_email, null,
        auth.private_key, ['https://www.googleapis.com/auth/drive']);

    try {
        const tokens = await jwtClient.authorize();
        let drive = google.drive('v3');

        const res1 = await drive.files.list({
            auth: jwtClient, q: `name = 'MyFolder'`
        });

        const folder = res1.data.files[0];

        const res2 = await drive.files.list({
            auth: jwtClient,
            q: `'${folder.id}' in parents`
        });

        // print out all files under MyFolder
        res2.data.files.forEach(f => console.log(f.name, f.id));

        const dest = fs.createWriteStream('./myfile.csv');
        const file = res2.data.files[0];

        const response = await drive.files.export({
            fileId: file.id,
            mimeType: file.mimeType,
            auth: jwtClient
        }, {
            responseType: 'stream'
        });

        response.data.on('error', err => {
            console.log(err);
        }).on('end', () => {
            console.log('done');
        }).pipe(dest);
    }
    catch (err) {
        console.log('The API returned an error: ', err);
    }
})();

这是导致错误的一部分:

The API returned an error:
... at Gaxios.<anonymous> (/api-test/node_modules/gaxios/build/src/gaxios.js:73:27)

 Response {
  size: 0,
  timeout: 0,
  [Symbol(Body internals)]: 
   { body: 
      Gunzip {
        _readableState: [Object],
        readable: true,
        domain: null,
        _events: [Object],
        _eventsCount: 7,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: true,
        _transformState: [Object],
        bytesRead: 0,
        _opts: [Object],
        _chunkSize: 16384,
        _flushFlag: 2,
        _finishFlushFlag: 2,
        _scheduledFlushFlag: 0,
        _handle: [Object],
        _hadError: false,
        _buffer: <Buffer 00 00 00 00 00 00 00 00 34 00 00 00 00 00 00 00 ... >,
        _offset: 0,
        _level: -1,
        _strategy: 0 },
     disturbed: false,
     error: null },
  [Symbol(Response internals)]: 
   { url: 'https://www.googleapis.com/drive/v3/files/123abc123abc/export?mimeType=text%2Fplain',
     status: 403,
     statusText: 'Forbidden',
     headers: Headers { [Symbol(map)]: [Object] },
     counter: 0 } }

我无法在错误中找到任何说明抛出 403 的原因。它似乎已压缩,但我无法成功解压缩其中的任何部分。

【问题讨论】:

  • 我能问一下你要下载的原始mimeType吗?你能提供错误信息吗?从这些信息中,我想尝试确认it has something to do with the service account not having permissions的情况。
  • @Tanaike mime 类型是text/plain。我无法在错误中找到任何有关导致 403 的原因的有用消息。我已更新帖子以包含更多错误消息。
  • 感谢您的回复。根据您的回复和附加信息,我提出了一个修改点。你能确认一下吗?如果这不是您想要的结果,我深表歉意。
  • @Tanaike 你搞定了。我没有意识到下载和导出之间的区别。说得通。谢谢!
  • 很高兴您的问题得到了解决。也谢谢你。

标签: node.js google-drive-api


【解决方案1】:
  • 您想从 Google 云端硬盘下载text/plain 的文件。

如果我的理解是正确的,那么这个修改呢?

修改点:

  • 我认为您的问题的原因是使用Drive API的files.export方法下载了text/plain的mimeType文件。
    • 下载 Google Docs(电子表格、文档、幻灯片等)文件时,可以通过 Drive API 的 files.export 方法完成。
    • 当您要下载除Google Docs以外的文件时,请使用files.get方法。
    • 当我尝试使用 files.export 方法下载text/plain 的文件时,我可以确认发生了同样的错误。

为了体现以上几点,请作如下修改。

修改脚本:

从:
const response = await drive.files.export({
    fileId: file.id,
    mimeType: file.mimeType,
    auth: jwtClient
}, {
    responseType: 'stream'
});
到:
const response = await drive.files.get({
    fileId: file.id,
    alt: "media",
    auth: jwtClient
}, {
    responseType: 'stream'
});

参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多