Google 前端选择器(用户在 reactJS 中登录)和 google 驱动后端下载(node.js),API v3

Google picker on frontend (user login in reactJS) and google drive download on backend (node.js), API v3

我正在构建一个文件上传器,它为用户提供了从他的 google 驱动器上传文件的选项。 Google picker 已设置并在前端 (reactJS) 上工作,我有 Google Picker 提供的文件 ID 和 OAuth 令牌。我将这些发送到后端 (node.js) 并将 Google 驱动器 API 放在那里。我按照文档 https://developers.google.com/drive/api/v3/manage-downloads 并将 oauth 令牌放在 drive.files.get 的 auth 参数中,现在我得到以下错误

Error  GaxiosError: [object Object]
    at Gaxios._request (/home/.../node_modules/gaxios/src/gaxios.ts:112:15)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  response: {
    config: {
      url: 'https://www.googleapis.com/drive/v3/files/1GqxjzMjrDdJquOPeMrFGIMngE20vTrjU?alt=media&key=ya29.6q33c6T418VuSILwq...cLKnBMKEG4vhui8K',
      method: 'GET',
      responseType: 'stream',
      userAgentDirectives: [Array],
      paramsSerializer: [Function],
      headers: [Object],
      params: [Object],
      validateStatus: [Function],
      retry: true,
      retryConfig: [Object]
    },
    data: PassThrough {
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: true,
      _transformState: [Object],
      [Symbol(kCapture)]: false
    },
    headers: {
      'alt-svc': 'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
      'cache-control': 'private, max-age=0',
      connection: 'close',
      'content-length': '176',
      'content-type': 'application/json; charset=UTF-8',
      date: 'Wed, 16 Dec 2020 11:42:15 GMT',
      expires: 'Wed, 16 Dec 2020 11:42:15 GMT',
      server: 'UploadServer',
      vary: 'Origin, X-Origin',
      'x-guploader-uploadid': 'ABg5-Uw8z7O1Hpe1od4_dQF9So652TfYS0Mc1vpIu3t4DDXPzB7YvNwQAeHKCvoNBF-7m_pW9e8EHPOgrEHS84HWR7M'
    },
    status: 400,
    statusText: 'Bad Request',
    request: {
      responseURL: 'https://www.googleapis.com/drive/v3/files/1GqxjzMjrDdJquOPeMrFGIMngE20vTrjU?alt=media&key=ya29.6q33c6T418VuSILwq...cLKnBMKEG4vhui8K'
    }
  },
  config: {
    url: 'https://www.googleapis.com/drive/v3/files/1GqxjzMjrDdJquOPeMrFGIMngE20vTrjU?alt=media&key=ya29.6q33c6T418VuSILwq...cLKnBMKEG4vhui8K',
    method: 'GET',
    responseType: 'stream',
    userAgentDirectives: [ [Object] ],
    paramsSerializer: [Function],
    headers: {
      'x-goog-api-client': 'gdcl/4.4.3 gl-node/12.19.0 auth/6.1.3',
      'Accept-Encoding': 'gzip',
      'User-Agent': 'google-api-nodejs-client/4.4.3 (gzip)'
    },
    params: {
      alt: 'media',
      key: 'ya29.6q33c6T418VuSILwq...cLKnBMKEG4vhui8K'
    },
    validateStatus: [Function],
    retry: true,
    retryConfig: {
      currentRetryAttempt: 0,
      retry: 3,
      httpMethodsToRetry: [Array],
      noResponseRetries: 2,
      statusCodesToRetry: [Array]
    }
  },
  code: '400'
}

我在这里观察到,有一个“关键”参数,但据我了解,应该有一个授权令牌。我尝试使用来自 POSTMAN 的文件 url 使用带有授权承载的 GET 调用,但它以登录页面响应。

问题:

  1. 既然我提供了一个token,它不应该直接下载文件吗?
  2. 为什么后台没有下载文件?

注意:我确实按照 google 驱动器 api 上的 node.js 文档进行了操作,但即使这样也会提示用户登录,但情况并非如此。

编辑:也添加了客户端代码

客户端(reactjs)

                <GooglePicker
                    clientId={"7...b.apps.googleusercontent.com"}
                    developerKey={"AIz...PY"}
                    scope={["https://www.googleapis.com/auth/drive.readonly"]}
                    onChange={handleFileChange}
                    onAuthenticate={(token) => setDownloadToken(token)}
                    onAuthFailed={(data) => console.log("on auth failed:", data)}
                    multiselect={false}
                    navHidden={false}
                    authImmediate={false}
                    query={"a query string like .txt or fileName"}
                    viewId={"PDFS"}
                >
                    <Button variant="contained" size="small">
                        G-Drive
                    </Button>
                </GooglePicker>{" "}

Node.js代码

export const googleDriveUpload = async (_, {fileID, authToken}) => {
  console.log(fileID, authToken);
  const drive = google.drive({version: 'v3', auth:authToken});

  var dest = fs.createWriteStream('/tmp/resume.pdf');

  drive.files.get({fileId: fileID, alt: 'media'}, 
  {responseType: 'stream'}, (err,  res ) => {
    if (err) {
      console.log("Error " ,err);
    } else {
        res.data.pipe(file);
        console.log("Download complete");
    }
  });
  • 定义const drive = google.drive({version: 'v3', auth:XXX})时,需要将函数authorize()的响应赋值给auth,如quickstart for Drive API in node.js
  • 请按照完整的快速入门获取经过身份验证的有效客户端