【问题标题】:Administrator Views for a Firebase Web Application: How ToFirebase Web 应用程序的管理员视图:如何
【发布时间】:2018-07-20 11:37:42
【问题描述】:

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

我的想法是,如果 .get() 由于未经授权的访问而失败,我会告诉我的应用程序逻辑用户不是管理员,如果 .get() 成功,我的逻辑会显示“管理员”部分。当然,“部分”只是由数据库填充的 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 规则通过 UID 指定“管理员”。

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

【问题讨论】:

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


    【解决方案1】:

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

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

    但您可能还需要考虑另一种选择:为您的管理员用户设置一个自定义声明,然后您可以在 server-side security rules(强制授权访问)和 front-end(优化 UI)中读取该声明.

    set a custom claim you use the Firebase Admin SDK。您可以在 Cloud Functions 中的自定义服务器上执行此操作,但在您的场景中,仅从您的开发机器上运行它可能会更简单。

    【讨论】:

    • dangit,Control Access with Custom Claims and Security Rules 正是完成这项工作的合适工具,我又在用锤子了。现在我必须阅读并消化更多信息。这好有趣。好东西。
    • 弗兰克,我认为这个 AdminSDK 功能应该在 firebase.google.com 网络用户界面(“控制台”)中可用。换句话说,我应该能够直接在控制台中配置自定义令牌或多级访问 (MLA) 令牌。我想我想说的是功能请求。我必须这样做。
    • 同意,这听起来是一个非常有用的功能,可以在控制台(或在 CLI 中)。请file a feature request。但与此同时,Admin SDK 是必经之路。
    • 我做了,提交功能请求。谢谢一百万弗兰克
    【解决方案2】:

    详细操作方法:Firebase 对此功能有所谓的自定义声明,如其Control Access with Custom Claims and Security Rules 中所述。基本上,你建立一个单独的节点服务器,安装 Firebase AdminSDK:

    npm install firebase-admin --save
    

    Generate/Download a Private Key 在 Firebase 控制台的“服务帐户”选项卡中,并将其放在您的节点服务器上。然后简单地创建一个简单的节点应用程序来为您希望的每个 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.");
    });
    

    就是这样。现在,您可以通过注销您的应用(如果您之前已登录)并在更新 Web 应用的 .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
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 2015-07-22
      • 1970-01-01
      相关资源
      最近更新 更多