【问题标题】:Firebase Callable function with JWT Authentication and Google Sheets V4 API带有 JWT 身份验证和 Google Sheets V4 API 的 Firebase 可调用函数
【发布时间】:2019-02-18 00:49:06
【问题描述】:

我想使用 Google Sheets V4 API 实现具有 JWT 身份验证和从 Google Sheet 获取数据的 firebase 可调用函数。 对于测试,我尝试使用 Example Spreadsheet,但未为该电子表格激活 Sheets API,我将其克隆到自己的驱动器上并用于测试。

参考资料: 我的代码基于此问题How to use Google sheets API while inside a google cloud functionAccessing Google APIs using Service account in Node.JS 中描述的解决方案

我还有两个重要信息:"Service Account".jsonAPI Key。我将 API 密钥保存在 api_key.json 中,但没有找到如何将其与 Google Sheets V4 API 一起使用的示例:

{ 
  key: "xxxxxx"
}

test() 不需要任何身份验证的可调用函数可以正常工作:

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 };
});

【问题讨论】:

    标签: firebase google-cloud-functions google-sheets-api


    【解决方案1】:

    有一个 solution 使用 googleapis 而不是 auth 库来使用 JWT 进行身份验证。关于令牌查询,您可以查看OAuth 2.0 for client-side web applications 文档,其中解释了进行身份验证的步骤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-19
      • 1970-01-01
      • 2019-08-04
      • 2021-08-18
      • 1970-01-01
      • 2019-02-14
      • 2021-10-30
      • 2020-06-18
      相关资源
      最近更新 更多