使 http 云函数只能由项目所有者执行

Make http cloud function executable only by the project owner

我正在使用 http 云功能 (https://firebase.google.com/docs/functions/http-events) 将文档写入 firestore 集合:

exports.hello = functions.https.onRequest(
  (req: { query: { name: string } }, res: { send: (arg0: string) => void }) => {
    console.log(req.query.name);
    var name = req.query.name || 'unknown';
    res.send('hello' + name);
    admin
      .firestore()
      .collection('ulala')
      .doc()
      .set({ token: 'asd' }, { merge: true });
  }
);

这是一个测试。问题是,一旦你部署并获得 link 到函数,它就可以被每个人执行。相反,我希望只有我(项目所有者)可以使用它。可以这样做吗?

一种可能的解决方案是将您的 HTTPS 云功能限制为仅供您应用的特定“管理员”用户使用。

有一个官方 Cloud Function 示例展示了如何将 HTTPS 函数限制为仅 app/Firebase 项目的 Firebase 用户:Authorized HTTPS Endpoint sample.

您需要修改它来检查用户是否是管理员用户。例如,通过检查 index.js 文件(未测试)的 try/catch block at line 60 中的用户 ID。

try {
    const decodedIdToken = await admin.auth().verifyIdToken(idToken);
    if (decodedToken.uid !== "<the admin user uid>") {
        throw new Error("Wrong user");
    } else {
        req.user = decodedIdToken; 
        next();                
    }
    return;
} catch (error) {
    functions.logger.error('Error while verifying Firebase ID token:', error);
    res.status(403).send('Unauthorized');
    return;
}

这种方法的两个缺点是:

  • 您的管理员用户需要在身份验证服务中声明为 Firebase 项目用户
  • 您在 Cloud Function 中对 Admin 用户 ID 进行了硬编码(您可以使用 Google Cloud Secret Manager 服务将其安全地存储为配置值,请参阅 doc)。

重要附注:

在您的 Cloud Function 中,您在异步工作完成之前调用了 send() 方法:

res.send('hello' + name);
admin
  .firestore()
  .collection('ulala')
  .doc()
  .set({ token: 'asd' }, { merge: true });

通过调用 send() 方法,您实际上终止了 Cloud Functions,向 Cloud Functions 实例 运行 表明您的函数可以关闭。因此在大多数情况下,异步 set() 操作不会被执行。

您需要进行如下操作:

admin
  .firestore()
  .collection('ulala')
  .doc()
  .set({ token: 'asd' }, { merge: true })
.then(() => {
   res.send('hello' + name);
})

我建议您观看 Firebase video series as well as read this page of the documentation 中关于“JavaScript Promises”的 3 个视频,其中解释了这个关键点。