如何保护 Firebase Firestore 中的一些数据?

How to protect some data in firebase firestore?

我正在尝试在我的网络应用程序中创建聊天室。该聊天室将受密码保护。如何安全地存储密码?

我是这么想的:

我知道我可以更改一些 firebase 安全规则,但是:

或者有更好的方法吗?

我发现的最简单的方法是您不必在 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 规则,但必须具有匹配的数据结构。