如何保护 Firebase Firestore 中的一些数据?
How to protect some data in firebase firestore?
我正在尝试在我的网络应用程序中创建聊天室。该聊天室将受密码保护。如何安全地存储密码?
我是这么想的:
- 通过我自己的 api 验证,它只能访问该密码。
我知道我可以更改一些 firebase 安全规则,但是:
- 我必须制作新的 collection 吗?还是我只能更改文档中一个字段的安全规则?
- 如何让 collection 仅供 api 访问?我知道我可以更改安全规则,通过 how to make it for api?
某些数据只能由其创建者访问
或者有更好的方法吗?
我发现的最简单的方法是您不必在 Firestore 中存储密码,而是可以使用 Firebase 身份验证。
您可以通过调用 createUserWithEmailAndPassword, or you can also create new password-authenticated users from the Authentication section as mentioned in Manage Users in Firebase 来创建它。
我设法通过使用 firebase 函数做到了这一点。我创建了将房间与用户相匹配的集合。
一个函数用于:
如果请求中传递的密码对于请求中也传递了 id 的房间是正确的,则将文档添加到与传递的用户 id 匹配此房间的集合。
还有一个:
Return id 与用户id 关联的所有房间的数据。
下面的代码我帮助它会帮助任何人:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const cors = require('cors')({ origin: true });
admin.initializeApp(functions.config().firebase);
exports.passwordCheck = functions.region("europe-central2").https.onRequest((req, res) => {
cors(req, res, () => {
const { uid, password, id } = req.body;
// refs to room with given args
const roomRef = admin.firestore()
.collection('rooms').doc(id)
roomRef.get().then((doc) => {
if (doc.data().password == password) {
// ref to room_members list in requested room
const room_members = admin.firestore().collection('room_members');
const is_member = room_members.where("user_uid", "==", uid).where("room_id", "==", id);
is_member.get().then((docs) => {
if (docs.docs.length == 0) {
room_members.add({
user_uid: uid,
room_id: id,
}).then(() => {
res.status(200).end();
})
}
}).catch(err => {
// user already in members
});
// Success status
}
else {
// wrong password
res.status(400).end();
}
}).catch(err => {
// not found room
res.status(404).end();
});
});
});
/* Example request for that function
curl -X POST https://europe-central2-xxx.cloudfunctions.net/passwordCheck
-H 'Content-Type: application/json'
-d '{"uid": "B2Xidd3Vw1PL9Kyt5ERFXCjniuF3","id":"Sjucgsyuw2723"
"password": "xxxx"}'
*/
exports.rooms = functions.region("europe-central2").https.onRequest((req, res) => {
cors(req, res, () => {
const { uid } = req.body;
// refs to rooms members list objects with given user id
const membersRef = admin.firestore()
.collection('room_members').where("user_uid", "==", uid);
membersRef.get().then((doc) => {
if (doc) {
// get all ids of rooms that user is in
const rooms_ids = doc.docs.map((docx) => { return docx.data().room_id });
// get all datas from that rooms
const roomsrefs = rooms_ids.map(id => admin.firestore().collection("rooms").doc(id));
admin.firestore().getAll(...roomsrefs).then((rooms) => {
res.json(rooms.map(room =>
Object.assign({}, { "id": room.id }, room.data())))
res.status(200).end();
})
}
else {
// not found resurces
res.json([]);
res.status(401).end();
}
}).catch(err => {
//Internal server error
res.status(500).end();
});
})
});
/* Example request for that function
curl -X POST https://europe-central2-xxxx.cloudfunctions.net/rooms
-H 'Content-Type: application/json'
-d '{"uid": "B2Xidd3Vw1PL9Kyt5ERFXCjniuF3"}'
// */
函数的响应时间大约为 500 毫秒,所以我确信这不是最佳解决方案,但它确实有效:)
也可以使用 firestore 规则,但必须具有匹配的数据结构。
我正在尝试在我的网络应用程序中创建聊天室。该聊天室将受密码保护。如何安全地存储密码?
我是这么想的:
- 通过我自己的 api 验证,它只能访问该密码。
我知道我可以更改一些 firebase 安全规则,但是:
- 我必须制作新的 collection 吗?还是我只能更改文档中一个字段的安全规则?
- 如何让 collection 仅供 api 访问?我知道我可以更改安全规则,通过 how to make it for api? 某些数据只能由其创建者访问
或者有更好的方法吗?
我发现的最简单的方法是您不必在 Firestore 中存储密码,而是可以使用 Firebase 身份验证。
您可以通过调用 createUserWithEmailAndPassword, or you can also create new password-authenticated users from the Authentication section as mentioned in Manage Users in Firebase 来创建它。
我设法通过使用 firebase 函数做到了这一点。我创建了将房间与用户相匹配的集合。
一个函数用于: 如果请求中传递的密码对于请求中也传递了 id 的房间是正确的,则将文档添加到与传递的用户 id 匹配此房间的集合。
还有一个: Return id 与用户id 关联的所有房间的数据。
下面的代码我帮助它会帮助任何人:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const cors = require('cors')({ origin: true });
admin.initializeApp(functions.config().firebase);
exports.passwordCheck = functions.region("europe-central2").https.onRequest((req, res) => {
cors(req, res, () => {
const { uid, password, id } = req.body;
// refs to room with given args
const roomRef = admin.firestore()
.collection('rooms').doc(id)
roomRef.get().then((doc) => {
if (doc.data().password == password) {
// ref to room_members list in requested room
const room_members = admin.firestore().collection('room_members');
const is_member = room_members.where("user_uid", "==", uid).where("room_id", "==", id);
is_member.get().then((docs) => {
if (docs.docs.length == 0) {
room_members.add({
user_uid: uid,
room_id: id,
}).then(() => {
res.status(200).end();
})
}
}).catch(err => {
// user already in members
});
// Success status
}
else {
// wrong password
res.status(400).end();
}
}).catch(err => {
// not found room
res.status(404).end();
});
});
});
/* Example request for that function
curl -X POST https://europe-central2-xxx.cloudfunctions.net/passwordCheck
-H 'Content-Type: application/json'
-d '{"uid": "B2Xidd3Vw1PL9Kyt5ERFXCjniuF3","id":"Sjucgsyuw2723"
"password": "xxxx"}'
*/
exports.rooms = functions.region("europe-central2").https.onRequest((req, res) => {
cors(req, res, () => {
const { uid } = req.body;
// refs to rooms members list objects with given user id
const membersRef = admin.firestore()
.collection('room_members').where("user_uid", "==", uid);
membersRef.get().then((doc) => {
if (doc) {
// get all ids of rooms that user is in
const rooms_ids = doc.docs.map((docx) => { return docx.data().room_id });
// get all datas from that rooms
const roomsrefs = rooms_ids.map(id => admin.firestore().collection("rooms").doc(id));
admin.firestore().getAll(...roomsrefs).then((rooms) => {
res.json(rooms.map(room =>
Object.assign({}, { "id": room.id }, room.data())))
res.status(200).end();
})
}
else {
// not found resurces
res.json([]);
res.status(401).end();
}
}).catch(err => {
//Internal server error
res.status(500).end();
});
})
});
/* Example request for that function
curl -X POST https://europe-central2-xxxx.cloudfunctions.net/rooms
-H 'Content-Type: application/json'
-d '{"uid": "B2Xidd3Vw1PL9Kyt5ERFXCjniuF3"}'
// */
函数的响应时间大约为 500 毫秒,所以我确信这不是最佳解决方案,但它确实有效:)
也可以使用 firestore 规则,但必须具有匹配的数据结构。