Функция Firebase Callable с аутентификацией JWT и API Google Sheets V4 - PullRequest
0 голосов
/ 13 сентября 2018

Я хочу реализовать функцию вызываемой в firebase функции с аутентификацией JWT и извлечением данных из Google Sheet, используя Google Sheets V4 API.Для тестирования я попытался использовать Пример электронной таблицы , но API листов не активирован для этой электронной таблицы, и я клонировал ее на своем собственном диске и использовал для тестирования.

Ссылки: Мой код основан на решении, описанном в этом вопросе Как использовать API листов Google в облачной функции Google и Доступ к API Google с помощью учетной записи службы в Node.JS

Также у меня есть две важные данные: «Сервисная учетная запись» .json и API Key .Я сохранил ключ API в файле api_key.json, но не нашел примеров, как использовать его с Google Sheets V4 API:

{ 
  key: "xxxxxx"
}

функция вызова (), которая не требует никакой аутентификации, работает нормально:

exports.test = functions.https.onCall((data, context) => {
  return { text: data.text };
});

Вызов функции test () где-нибудь на клиенте (в браузере):

function getTest() {
  console.log("clicked getTest()");
  var test = firebase.functions().httpsCallable('test');

  test({text: '12345'}).then(function(result) {
    console.log(result);
  }).catch(function(error) {
    console.log(error.code);
    console.log(error.message);
  });
}

Вызов getData () где-нибудь на клиенте (в браузере):

function requestData() {
  console.log("clicked requestData()");

  //https://firebase.google.com/docs/functions/callable
  //getData() function described in functions/index.js

  var getData = firebase.functions().httpsCallable('getData');

  getData(null).then(function (result) {
    // Read result of the Cloud Function.
    console.log(result);  //<------- Expected rows from Spreadsheet????
  }).catch(function(error) {
    console.log(error.code);
    console.log(error.message);
  });
}

** Спасибо, F10.Я исправил код.index.js:

'use strict'
const functions = require('firebase-functions');
const { google } = require('googleapis');
var serviceAccount = require("./credentials/owner-service-account-gcloud.json");

function getJwt() {
  // Define the required scopes.
  var scopes = [
    'https://www.googleapis.com/auth/spreadsheets'
  ];
  return new google.auth.JWT(
    serviceAccount.client_email,
    null,
    serviceAccount.private_key,
    scopes
  );
}

function getSpreadsheetDate(jwt) {

  return new Promise((resolve, reject) => {
    jwt.authorize((error, access_token) => {
      if (error) {
        console.log('Error in jwt.authorize: ' + error);
        reject(error);
      } else {
        // access_token ready to use to fetch data and return to client
        const sheets = google.sheets({ version: 'v4', access_token });

        // set auth as a global default:
        google.options({ auth: jwt }); //<---------------------- 

        const request = {
          auth: jwt,
          spreadsheetId: 'xxxx',
          range: 'Class Data!A2:E', //'Class Data!A2:E',
        }

        sheets.spreadsheets.values.get(request, (err, response) => {
          console.log("inside: sheets.spreadsheets.values.get() -------------------------------");

          if (err) {
            console.log('The Sheets API returned an error: ' + err);
            //The API returned an error: Error: API key not valid. Please pass a valid API key.
            reject(err);
          };

          try {
            var numRows = response.data.values ? response.data.values.length : 0;
            console.log('%d rows retrieved.', numRows);

            console.log("response.data:-------------------------------");
            console.log(response.data.values);

            resolve(response.data.values);

          } catch (err) {
            console.log("Error processing Sheets API response: " + err);
            reject(err);
          }

        })

      }
    })
  })

}


exports.getData = functions.https.onCall((data, context) => {
  console.log("getData()---------------------------");
  if (!context.auth) {
    throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' + 'while authenticated.');
  } else {
    console.log("context.auth ------------ OK");
    const uid = context.auth.uid;
    console.log(uid);

    var jwt = getJwt();
    console.log("getJwt() --------------- OK");

    return getSpreadsheetDate(jwt); //<------------ Requested Spreadsheet's Data

  }
})

exports.test = functions.https.onCall((data, context) => {
  return { text: data.text };
});

1 Ответ

0 голосов
/ 13 сентября 2018

Существует решение , которое использует googleapis вместо библиотеки аутентификации для аутентификации с помощью JWT. Что касается запросов токенов, вы можете проверить документацию OAuth 2.0 для клиентских веб-приложений , в которой поясняются шаги для выполнения аутентификации.

...