要在Firestore中添加/更新/删除记录,我可以在执行此操作的应用程序中运行代码,也可以调用处理此操作的云函数。是";"更安全";让我的应用程序以云功能的方式实现它?这种方式需要更长的时间,但我担心Firebase会以某种方式变得脆弱。我曾经读到,为了制作一个真正安全的应用程序,你应该假设某个恶意用户已经对你的应用程序进行了逆向工程。我应该假设对Firestore的所有更改使用云函数是最安全的途径吗?还是没有区别?
使用客户端的代码:
CollectionReference users = FirebaseFirestore.instance.collection('users');
Future<void> addUser() {
// Call the user's CollectionReference to add a new user
return users
.add({
'full_name': fullName, // John Doe
'company': company, // Stokes and Sons
'age': age // 42
})
.then((value) => print("User Added"))
.catchError((error) => print("Failed to add user: $error"));
}
使用云功能:
exports.createUser = functions.https.onCall(async (data, context) => {
const uid = context?.auth?.uid
if (!uid) {
return {result: 0, message: 'You are not authorized.'}
}
const username = data.user
const email = data.email
var result: number
var message: string
//Check to see if that username already exists
const doesUserExist = await TS_doesUserExist(username)
const createUser = await TS_createUser(uid, username, email)
if (doesUserExist[0] == 0) {
if (createUser[0] == 1) {
result = 1
message = ''
} else {
result = 0
message = createUser[1]
}
} else {
result = 0
message = doesUserExist[1]
}
return {result: result, message: message}
})
async function TS_createUser(uid: string, username: string, email: string): Promise<[number, string]> {
var result: number = 0
var message: string = ''
//Create SECURE_userinfo doc
const userInfoDoc = await admin.firestore()
.collection(usersCollPath)
.doc(uid) // use uid as document ID
.collection(secureUserInfoCollPath)
.doc()
.set({
createDate: admin.firestore.FieldValue.serverTimestamp(), //signupdate
email: email,
})
//Create stat doc
const statDoc = await admin.firestore()
.collection(usersCollPath)
.doc(uid)
.collection(statCollPath)
.doc()
.set({
stat: 1,
})
//Create username doc
const usernameDoc = await admin.firestore()
.collection(usersCollPath)
.doc(uid)
.collection(usernameCollPath)
.doc()
.set({
username: username,
})
if (userInfoDoc) {
if (statDoc) {
if (usernameDoc) {
result = 1
message = ''
} else {
result = 0
message = 'Could not create username doc'
}
} else {
result = 0
message = 'Could not create status doc'
}
} else {
result = 0
message = 'Could not create user info doc'
}
return [result, message]
}
这取决于你所说的"安全";。将数据库逻辑放在函数后面只会使攻击者使用该函数而不是数据库接口进行滥用。它们都是非常有用的攻击载体。
直接数据库访问(使用安全规则(与云函数之间的主要区别在于,您在签入函数的输入方面更有表现力,因为您可以完全使用JavaScript。这为您提供了比安全规则更多的选择,但不一定是"更安全";无论如何。
我有一个已建立的Flutter应用程序,它主要使用Flutterfire直接调用Firestore,但在某些情况下会调用云函数。如果云函数最近没有被同一用户或另一用户调用,那么第一次调用时会有明显的延迟。
如果:,我建议使用直接Firestore访问
- 速度对您的用户体验至关重要;以及
- 您可以实施有效的安全规则来防范风险
Doug指出,直接访问和通过云功能访问仍然存在需要管理的漏洞。