我有一套结构化的Firestore规则,除了自定义JWT中的自定义用户声明外,其他所有功能都正常运行。
我正在使用Laravel框架,将kreait/firebase-php与createCustomToken
一起使用,
'firebase_custom_token' => (string)$firebase->getAuth()->createCustomToken(
"mrp-admin-user:{$user->id}", [
'isPanel' => true,
'userRoles' => $user->roleIds // returns an array like ['admin', 'operator']
]
)
然后在客户端,我就可以像这样成功登录Firebase:
firebase.auth().signInWithCustomToken(firebase_custom_token);
我有一个Firestore规则功能,该功能通过检查isPanel == true
令牌声明来检查用户是否为面板用户:
function isPanelUser() {
return request.auth != null &&
'isPanel' in request.auth.token &&
request.auth.token.isPanel == true
}
使用该功能的所有操作都会失败,并出现缺少权限或权限不足错误:
match /users/{userId}/{document=**} {
allow read, write: if isSignedInAs(userId) || isPanelUser();
}
match /system/services/{serviceId}/{document=**} {
allow read;
allow write: if isPanelAdmin();
}
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /system/config {
allow read;
allow write: if isPanelAdmin();
}
match /services/{serviceId}/{document=**} {
allow read;
allow write: if isPanelAdmin();
}
match /orders/{orderId}/{document=**} {
allow read, write: if isPanelUser() || isSignedInAs(resource.data.uid);
}
match /users/{userId}/{document=**} {
allow read, write: if isSignedInAs(userId) || isPanelUser();
}
match /drivers/{userId}/{document=**} {
allow read, write: if isSignedInAs(userId) || isPanelUser();
}
function isSignedIn() {
return request.auth != null
}
function isSignedInAs(uid) {
return request.auth != null && request.auth.uid == uid
}
function isPanelUser() {
return request.auth != null &&
'isPanel' in request.auth.token &&
request.auth.token.isPanel == true
}
function isPanelUserOfRole(role) {
return isPanelUser() == true &&
'userRoles' in request.auth.token &&
role in request.auth.token.userRoles
}
function isPanelSuperAdmin() {
return isPanelUser() == true &&
'userRoles' in request.auth.token &&
'super-admin' in request.auth.token.userRoles
}
function isPanelAdmin() {
return isPanelUser() == true &&
'userRoles' in request.auth.token && (
'admin' in request.auth.token.userRoles ||
'super-admin' in request.auth.token.userRoles
)
}
function isPanelOperator() {
return isPanelUser() == true &&
'userRoles' in request.auth.token && (
'operator' in request.auth.token.userRoles ||
'admin' in request.auth.token.userRoles ||
'super-admin' in request.auth.token.userRoles
)
}
}
}
编辑
这是写入system/config
文档的javascript代码:
通知:如果我从system/config
规则中删除了写检查,那么它将起作用并写入文档。
import firebase from "firebase/app";
import 'firebase/firestore';
...
const systemConfigRef = firebase.firestore().collection('system').doc('config');
systemConfigRef.set({
status: 'down'
})
.then(docRef => {
console.log('System config written');
})
.catch(error => {
console.log('System config error', error); // getting permissions error
});
答案 0 :(得分:1)
您的系统/配置位置规则是:
match /system/config {
allow read;
allow write: if isPanelAdmin();
}
您要求用户是panelAdmin,这比不仅仅是面板用户有更严格的要求:
function isPanelAdmin() {
return isPanelUser() == true &&
'userRoles' in request.auth.token && (
'admin' in request.auth.token.userRoles ||
'super-admin' in request.auth.token.userRoles
)
}
您既需要将userRoles数组放置在令牌上,又需要在该数组中包含“ admin”或“ super-admin”。您绝对确定
'userRoles' => $user->roleIds
以管理员或超级管理员返回数组?我建议将规则切换为仅调用isPanelUser
而不是isPanelAdmin
进行测试。