Firebase Web应用程序的管理员视图:如何

时间:2018-02-09 16:34:14

标签: javascript firebase firebase-authentication google-cloud-firestore firebase-security-rules

我的Firebase网络应用需要管理员访问权限,即用户界面应仅向管理员显示一些内容(管理员'部分)。我想出了下面的方法来授权UI只显示有效管理员的管理部分。我的问题是,好还是坏?这是一种合理的授权方式吗? ......有很多方法可以做到这一点。这种特殊方式要求我在安全规则中配置管理员(vs在db / firestore中的节点/树中)

我的想法是,如果.get()由于未经授权的访问而失败,我告诉我的应用逻辑用户不是管理员,如果.get()成功我的逻辑显示' admin&# 39;部分。当然,'部分'只是数据库填充的HTML骨架/空元素,所以即使最终用户攻击JS /逻辑,也不会有真正的数据 - 只有空的管理部分'框架。

function isAdmin(){
    return new Promise(function(resolve, reject){
        var docRef = firebase.firestore().collection("authorize").doc("admin");
        docRef.get().then(function(result) {
            if (result) {
                resolve (true);
            }
        }).catch(function(error) {
            resolve (false);
        });
    });
}

firestore规则指定' admins'由UID。

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid == "9mB3UxxxxxxxxxxxxxxxxxxCk1";
    }
  }
}

2 个答案:

答案 0 :(得分:2)

您将每个用户的角色存储在数据库中,然后在客户端中查找以更新其UI。这曾经是很长时间在实时数据库上的惯用方式,它仍然适用于Firestore。

我唯一要改变的是让规则也从/authorize/admin读取,而不是在其中硬编码UID。这样,您只在一个地方拥有UID,而不是在规则和文档中都有它。

但您可能还想考虑另一种方法:为您的管理员用户设置自定义声明,然后您可以同时阅读server-side security rules(以强制授权访问)和front-end(至优化用户界面。)

set a custom claim you use the Firebase Admin SDK。您可以在云功能中的自定义服务器上执行此操作,但在您的方案中,从开发计算机运行它可能更简单。

答案 1 :(得分:1)

详细操作方法:Firebase具有此功能的自定义声明,详见其Control Access with Custom Claims and Security Rules。基本上,您站起来一个单独的节点服务器,安装Firebase AdminSDK:

npm install firebase-admin --save
从Firebase控制台的“服务帐户”标签中

Generate/Download a Private Key并将其放在节点服务器上。然后,只需创建一个裸骨节点应用程序,为您希望的每个UID(用户)分配自定义声明。像下面这样的东西对我有用:

var admin = require('firebase-admin');
var serviceAccount = require("./the-key-you-generated-and-downloaded.json");
admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://xxxxxxxxxxxxxxxxxxxx.firebaseio.com"
});
admin.auth().setCustomUserClaims("whatever-uid-you-want-to-assign-claim-to", {admin: true}).then(() => {
    console.log("Custom Claim Added to UID. You can stop this app now.");
});

就是这样。您现在可以通过退出应用程序(如果您之前已登录)验证是否已应用自定义声明,并在更新网络应用程序的.onAuthStateChanged方法后重新登录:

firebase.auth().onAuthStateChanged(function(user) {
    if (user) { 
        firebase.auth().currentUser.getIdToken()
            .then((idToken) => {
                // Parse the ID token.
                const payload = JSON.parse(window.atob(idToken.split('.')[1]));
                // Confirm the user is an Admin.
                if (!!payload['admin']) {
                    //showAdminUI();
                    console.log("we ARE an admin");
                }
                else {
                    console.log("we ARE NOT an admin");
                }
            })
            .catch((error) => {
                console.log(error);
            });
    }
    else {
        //USER IS NOT SIGNED IN
    }
});