Инструмент выбора Google на интерфейсе (вход пользователя в responseJS) и загрузка диска Google на серверной части (node.js), API v3

Я создаю загрузчик файлов, который предоставляет пользователю возможность загружать файлы с его диска Google. Средство выбора Google настроено и работает на интерфейсе (responseJS), и у меня есть идентификатор файла и токен OAuth, предоставленные средством выбора Google. Я отправляю их на бэкэнд (node.js), и у меня есть API Google Диска. Я следил за документацией https://developers.google.com/drive/api/v3/manage-downloads и поместите токен oauth в параметр auth в drive.files.get, теперь я получил следующую ошибку

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'
}

Здесь я заметил, что есть ключевой параметр, но, насколько я понимаю, должен быть токен авторизации. Я попытался использовать URL-адрес файла из POSTMAN с помощью вызова GET с носителем авторизации, но он ответил страницей входа.

Вопросов:

  1. Поскольку я предоставил токен, не следует ли загружать файл напрямую?
  2. Почему не скачивается файл на бэкэнде?

Примечание: я следил за документацией google drive 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");
    }
  });

person Siddhant Parekh    schedule 17.12.2020    source источник


Ответы (1)


  • Когда вы определяете const drive = google.drive({version: 'v3', auth:XXX}), вам необходимо назначить auth ответ функции authorize(), как показано в краткое руководство по Drive API в node.js
  • Следуйте инструкциям по быстрому запуску, чтобы получить действительного аутентифицированного клиента.
  • Если создание аутентификации с помощью клиента oAuth2 - не то, что вам нужно, существуют также другие варианты создания действительных учетных данных, см. клиентская библиотека google-api-nodejs
person ziganotschka    schedule 17.12.2020
comment
Я также добавил код на стороне клиента, где происходит аутентификация. Я уже получил токен из внешнего интерфейса выбора Google, в который входит пользователь! Этот токен я должен использовать для загрузки выбранного файла, верно? Что мне не хватает? - person Siddhant Parekh; 17.12.2020
comment
Google Picker и Google Drive API следуют разным потокам аутентификации. Если вы уже настроили Google Picker, почему бы вам не использовать его для загрузки файла напрямую с помощью XML-запроса вместо того, чтобы пытаться объединить его с Google Drive API? См. Образец здесь. - person ziganotschka; 17.12.2020
comment
Что ж, я должен загрузить файл в корзину s3 в бэкэнде и после этого обработать его. У меня уже есть конфигурация загрузки на бэкэнде, и я не хотел реплицировать ее на фронтенде, но я думаю, что это единственный оставшийся вариант. Большое спасибо за помощь @ziganotschka! - person Siddhant Parekh; 17.12.2020