首页 > 解决方案 > 如何确保我在 firebase 中的 getUserProfile 云函数仅在登录用户的会话请求时才返回数据?

问题描述

我有一个名为的云函数getUserProfile,如下所示:

exports.getUserProfile = functions.https.onRequest((request, res) => {
    try {
        const username = request.body.username || request.query.username;
        if (username == null || username.length == 0) return res.send('{"status":"error","errorMessage":"No username Provided."}');

        admin.database().ref().child("users").orderByChild("username").equalTo(username).once('value', snapshot => {
            if (!snapshot.exists()) return res.send(`{"status":"error","message":"invalid-profile"}`);
            
            snapshot.forEach(function(child) {
                const id = child.val().id;
                admin.database().ref('users/' + id).once('value', snapshot => {
                    if (!snapshot.exists()) return res.send('{"status":"error","errorMessage":"user not found."}');

                    let userData = {}
                    userData.username = snapshot.val().username || "N/A";
                    userData.name = snapshot.val().name || "N/A";
                    userData.email = snapshot.val().email || "N/A";

                    admin.database().ref('uploads').orderByChild('createdBy').equalTo(id).once('value', snapshot => {
                        userData.content = {};
                        const filePromise = [];
                        snapshot.forEach(function(child) {
                            let content = {};
                            content.id = child.key;
                            content.val = child.val();
                            content.val.files.forEach(function(fileId) {
                                filePromise.push(admin.database().ref().child("files").child(fileId.fileId).once("value"));
                            });

                            userData.content[child.key] = content;
                            userData.content[child.key].files = [];
                        });
                        Promise.all(filePromise).then(results => {
                            results.forEach((result => {
                                const uploadId = result.val().uploadId;
                                const thumbDownloadURL = result.val().thumbDownloadURL;
                                userData.content[uploadId].files.push(thumbDownloadURL);
                            }));
                            res.send(`{"status":"ok","userdata":${JSON.stringify(userData)}}`);
                        });
                    });

                });
            });

        });
    } catch (err) {
        res.send(`{"status":"error","message":"${err}"}`);
    }
});

我使用这个函数来获取用户配置文件的详细信息并将它们呈现在视图上。但是,如果有人从https://reqbin.com/发出请求并发送 {"username": "xxx"} JSON 内容,则该函数仍在返回数据,这是一个安全漏洞,这是一个预期的行为。如何确保只有登录用户才能获取数据?

标签: node.jsfirebase-realtime-databasefirebase-authenticationgoogle-cloud-functions

解决方案


您应该使用 JWT 身份验证来验证想要从您的 Firebase 云功能请求数据的用户。因此,当用户首次注册时,会为该用户分配一个令牌(可以在需要时更新或撤销),然后每当该用户想要请求数据时,他们需要通过将 Authentication: Bearer + UserJWToken 添加到请求标头来发送其令牌. 然后在云功能方面,您可以验证该令牌和

以下是一些可以帮助解决该主题的链接:

https://firebase.google.com/docs/auth/admin/create-custom-tokens

https://firebase.google.com/docs/auth/admin/verify-id-tokens

https://itnext.io/firebase-cloud-functions-verify-users-tokens-d4e60e314d1a


推荐阅读