使 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 个视频,其中解释了这个关键点。
我正在使用 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 个视频,其中解释了这个关键点。