我有一个带有内容管理端的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"
}
}
这似乎可以保护对数据库的写访问权限,但我无法使用相同的管理字段/令牌进行firebase存储,所以我必须这样做:
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
显示在客户端上,所以我现在没有办法重定向。
有人可以帮我解决这个问题吗?
答案 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令牌验证进行服务器端验证。