限制firebase数据库和对特定组的存储写入访问权限

时间:2018-03-09 14:55:48

标签: firebase firebase-realtime-database firebase-authentication firebase-storage firebase-security

我有一个带有内容管理端的react redux firebase应用程序(所有这些页面都以/admin/...开头)。我需要限制firebase数据库和firebase存储对这些用户的一小部分的写入访问权限,以及在未经身份验证(或经过身份验证但没有管理员角色)的用户尝试去那里时处理重定向。目前,任何发现auth按钮位于/admin的人都可以使用Facebook或Google登录,然后可以访问所有内容。

从我所看到的,看起来像是通过custom tokens做到这一点,但我不清楚他们提供的片段在哪里安全地做到这一点。我尝试通过Web控制台在firebase数据库中手动添加admin: true,然后设置我的firebase数据库规则,如下所示:

{
  "rules": {
    ".read": "true",
    ".write": "auth != null && root.child('users').child(auth.uid).child('admin').val() == true"
  }
}

这似乎可以保护对数据库的写访问权限,但我无法使用相同的管理字段/令牌进行fi​​rebase存储,所以我必须这样做:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth!=null && request.auth.uid=="{my uid}";
      //request.auth.token.admin==true did not seem to work
    }
  }
}

我也无法让admin: true显示在客户端上,所以我现在没有办法重定向。

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

限制对(和稳定)用户子集的访问的一种方法是使用他们的uid并检查它是否包含在admin用户uid数组中,如下所示:

function isAdminUser() {
   return request.auth.uid in [
        "UcqBSJOPDT........zzaeh1",
        "pQHSCZ1........hS2mfKmd2", 
        "MK8kif7.......eEqJzUl2n1", 
        "FrSm................XI82"
    ];
}

service firebase.storage {
  match /b/xxxxxxx.appspot.com/o {
    match /{allPaths=**} {
      allow write: .....;
      allow read: if request.auth != null && isAdminUser();
    }
  }
}

答案 1 :(得分:1)

Firebase通过ID令牌上的自定义用户声明支持对任何用户进行基于角色的访问:https://firebase.google.com/docs/auth/admin/custom-claims

您将定义管理员访问规则:

{
  "rules": {
    "adminContent": {
      ".read": "auth.token.admin === true",
      ".write": "auth.token.admin === true",
    }
  }
}

使用Admin SDK从服务器设置用户角色。您可以使用自己的服务器,或通过云功能中的onCreate事件设置此项(只要您可以告诉谁是管理员,谁不是来自那里)等等:

// Set admin privilege on the user corresponding to uid.
admin.auth().setCustomUserClaims(uid, {admin: true}).then(() => {
  // The new custom claims will propagate to the user's ID token the
  // next time a new one is issued.
});

这将传播到相应用户的ID令牌声明。

要从客户端上的令牌解析它,请检查:https://firebase.google.com/docs/auth/admin/custom-claims#access_custom_claims_on_the_client

您基本上需要base64解码令牌的有效负载。但是,如果您正在运行自己的服务器端代码,则始终依靠Firebase规则或ID令牌验证进行服务器端验证。