У меня есть структурированный набор правил 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
)
}
}
}
EDIT
Вот код JavaScript, который записывает в документ system/config
:
Замечание : Если я уберу проверку записи из правила 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
});