使用Google API进行异步身份验证

时间:2019-02-11 12:56:56

标签: javascript node.js asynchronous promise

我有以下代码:

async function initApi() {
  const googleKey = await readJSON(appRoot + '/secrets/google-auth.json');

  const jwt = new google.auth.JWT(
    googleKey.client_email, null, googleKey.private_key, scopes);

  return jwt.authorize();
}

const calendar = {
  events: events,

  api: google.calendar({
    version: 'v3',
    auth: this.jwt
  }),

  list: async function() {
    await this.api.calendarList.list();
  },
};

module.exports = async () => Object.assign(calendar, { jwt: await initApi() });

我不断收到“需要错误登录”。当我记录结果时,jwt可以很好地解析为访问令牌:

const Calendar = require('./above-code.js');

Calendar().then(c => console.log(c.jwt));
// { access_token: ... }

Calendar().then(c => console.log(c.list());
// Error: login required

我不知道为什么。这真让我发疯。我想把笔记本电脑丢到窗外。

我在做什么错?这是将asyncawaitmodule.exports一起使用的最佳模式吗?是否有更好的方法来返回对象,以便我可以调用Calendar.list()并获得结果,而不必跳过我当前为获得API并直接调用方法而做的工作?例如:

const Calendar = require('./above-code.js');
await Calendar.list();

3 个答案:

答案 0 :(得分:0)

您将jwt添加到对象中,而不是将其添加为单独的变量,因此应为:

  google.calendar({
    version: 'v3',
    auth: this.jwt //here
}),

Object.assign(calendar, { jwt: 'value' });等效于calendar.jwt = 'value'。您指的是好像是这样完成的:

let jwt  = 'value';
  google.calendar({
    version: 'v3',
    auth: jwt //here
}),

答案 1 :(得分:0)

在我回到这个问题之前稍作休息-在我遇到一个令人沮丧的问题之前,对自己最好的解决方案似乎已经变得越来越沮丧。

首先,我将api属性移到了initApi函数中,并在那儿返回了-这似乎解决了我的问题:

async function initApi() {
  const googleKey = await readJSON(appRoot + '/secrets/google-auth.json');

  const jwt = new google.auth.JWT(
    googleKey.client_email, null, googleKey.private_key, scopes);

  jwt.authorize();

  return google.calendar({
    version: 'v3',
    auth: jwt
  });
}

const calendar = {
  events: events,

  list: async function() {
    await this.api.calendarList.list();
  },
};

module.exports = async () => Object.assign(calendar, { api: await initApi() });

第二个警告是,现在它一直抱怨找不到client.request-事实证明Google有两套身份验证工具。

更改为google-auth-library后(而不是使用googleapis的内置auth.JWT),我收到了来自服务器的回复,没有client.request的投诉:< / p>

const { google } = require('googleapis');
const { JWT } = require('google-auth-library');

...

async function initApi() {
  const googleKey = await readJSON(appRoot + '/secrets/google-auth.json');

  const jwt = new JWT(
    googleKey.client_email, null, googleKey.private_key, scopes);

  return await google.calendar({
    version: 'v3',
    auth: jwt
  });
}

现在可以了!希望对任何有此问题的人有所帮助。

EDIT :此外,请参见Google的示例here,该示例用于从Google API信息中心的可下载JSON文件中加载身份验证。

答案 2 :(得分:0)

由于作者构建模块对象的方式,答案很难理解。

这里是使用promise的简化版本,不需要function rankings(arr){ // add whatever parameters you deem necessary....good luck! var sorted = arr.slice().sort(function(a,b){return b-a}) var ranks = arr.slice().map(function(v){ return sorted.indexOf(v) + 1 }); return ranks; } console.log(rankings([10, 5, 20]));

query = """UPSERT INTO test (testID) VALUES (%s)"""
#Connection code etc.
with conn.cursor() as cur:
      cur.execute(query, [results])
conn.commit()