我有一个使用Firebase Firestore的服务器端渲染的reactjs应用。
我在网站的某个区域中需要从Firestore检索服务器端的内容。
当前,我正在使用Firestore规则,允许任何人从这些特定文档中读取数据
让我担心的是,某些坏人可能会设置脚本来连续读取我的数据库并堆积我的帐单(因为我们是按每次阅读收取费用,允许任何人执行读取似乎是不明智的。)
当前规则
// Allow anonymous users to read feeds
match /landingPageFeeds/{pageId}/feeds/newsFeed {
allow read: if true;
}
如何允许我的服务器端脚本从Firestore中读取,但不允许其他人读取?
请记住,这是在服务器端运行之前执行的初始操作,然后以预加载状态为客户端充水。此功能/动作也与客户端共享以进行页面间导航。
我考虑了匿名登录-该方法有效,但是,每次页面加载都会生成一个新的匿名用户-Firebase确实限制了新的电子邮件/密码和匿名用户帐户。它似乎不切实际。
答案 0 :(得分:0)
根据Doug的评论,我进一步考虑了admin SDK。我最终在firebase函数中为需要安全的firestore读取且可以缓存的匿名请求创建了单独的API。
目标
管理SDK和Firebase函数缓存
admin SDK允许我安全地从firestore中读取。我的firestore security rules可以拒绝未经身份验证的用户的访问。
正在处理 GET 请求的Firebase函数支持server caching the response。这意味着来自相同查询的后续匹配不会重新运行我的所有功能(firebase读取,其他功能调用),而只是立即再次用相同的数据进行响应。
过程
res.set('Cache-Control', 'public, max-age=600, s-maxage=10800');
注意-缓存不适用于本地-必须部署到Firebase才能测试缓存效果。
const functions = require("firebase-functions");
const cors = require('cors')({origin: true});
const { sendResponse } = require("./includes/sendResponse");
const { getFirestoreDataWithAdminSDK } = require("./includes/getFirestoreDataWithAdminSDK");
const cachedApi = functions.https.onRequest((req, res) => {
cors(req, res, async () => {
// Set a cache for the response to limit the impact of identical request on expensive resources
res.set('Cache-Control', 'public, max-age=600, s-maxage=10800');
// If POST - response with bad request code - POST requests are not cached
if(req.method === "POST") {
return sendResponse(res, 400);
} else {
// Get GET request action from query
let action = (req.query.action) ? req.query.action : null;
console.log("Action: ", action);
try {
// Handle Actions Appropriately
switch(true) {
// Get Feed Data
case(action === "feed"): {
console.log("Getting feed...");
// Get feed id
let feedId = (req.query.feedId) ? req.query.feedId : null;
// Get feed data
let feedData = await getFirestoreDataWithAdminSDK(feedId);
return sendResponse(res, 200, feedData);
}
// No valid action specified
default: {
return sendResponse(res, 400);
}
}
} catch(err) {
console.log("Cached API Error: ", err);
return sendResponse(res, 500);
}
}
});
});
module.exports = {
cachedApi
}