如何在 Firestore 上以有限权限使用 Admin SDK?

IT技术 javascript firebase firebase-security google-cloud-functions google-cloud-firestore
2021-02-21 20:00:51

我在 Cloud 函数和 Firestore 规则方面遇到了一些麻烦。我想在 Firestore 上使用具有有限权限的云功能,并且只授予安全规则中定义的访问权限

它在 RTDB 上没有问题,但在 Firestore 上没有问题。

我已经尝试过这个规则

service cloud.firestore {
  match /databases/{database}/documents {

    match /init/{ID=**} {
        allow read, write: if true;
    }

    match /test/{ID=**} {
        allow read, write: if false;
    }
  }
}

还有这个

const admin = require('firebase-admin');
const functions = require('firebase-functions');
const FieldValue = require('firebase-admin').firestore.FieldValue;

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://******.firebaseio.com',
    databaseAuthVariableOverride: {
        uid: 'my-worker',
    },
});

const db = admin.firestore();

exports.onTestRights = functions.firestore
    .document('init/{initID}')
    .onCreate((event) => {
        const initID = event.params.initID;
        return db.collection('test').doc(initID).set({'random key': 'random value'}).then(()=>{
            console.log('working');
            return;
        }).catch((err) =>{
            console.log('error: ', err);
            return;
        });
    });

但它仍然是这样写的,而它应该是“权限被拒绝”

有人知道firestore上是否正常(或尚未植入)或我误解了什么?

编辑: 当然,我的最终目标不是使用此规则,而是仅使用 ( allow read, write: if request.auth.uid == 'my-worker';)授予对某些文档/集合的写/读访问权限

Edit2: 如果在使用此模型的过程中没有更改,我想使用安全规则进行检查

1个回答

正如您所注意到的,databaseAuthVariableOverride仅适用于实时数据库。现在没有任何东西可以让您在 Admin SDK 中对 Firestore 执行相同的操作。

如果您想限制对服务器代码的访问权限,可以使用的一种解决方法是使用客户端 JS SDK 而不是 Firebase Admin,并使用自定义令牌登录用户。这是执行此操作的示例代码:

// Configure Firebase Client SDK.
const firebase = require('firebase/app');
require('firebase/auth');
require('firebase/firestore');
firebase.initializeApp({
  // ... Initialization settings for web apps. You get this from your Firebase console > Add Firebase to your web app
});

// Configure Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

// Create Custom Auth token for 'my-worker'.
const firebaseReady = admin.auth().createCustomToken('my-worker').then(token => {
  // Sign in the Client SDK as 'my-worker'
  return firebase.auth().signInWithCustomToken(token).then(user => {
    console.log('User now signed-in! uid:', user.uid);

    return firebase.firestore();
  });
});

// Now firebaseReady gives you a Promise that completes with a authorized firestore instance. Use it like this:

exports.onTestRights = functions.firestore
  .document('init/{initID}')
  .onCreate(event => {
    const initID = event.params.initID;
    return firebaseReady.then(db => db.collection('test').doc(initID).set({'random key': 'random value'}).then(() => {
      console.log('working');
      return;
    }).catch((err) =>{
      console.log('error: ', err);
      return;
    });
  );
});
您的示例不起作用,我有此错误(pastebin.com/K5Bk7fRF)。在谷歌上查看后,我发现这是因为require('firebase/firestore');需要。因此,我通过 npm install 添加了所需的依赖项(grpc 和 protobufjs),但出现另一个错误:pastebin.com/gUCTu1Sh
2021-04-18 20:00:51
此功能在路线图上(我们想构建它),但我们还没有可以分享的时间表......
2021-04-21 20:00:51
@Nivco 使用最新版本,现在可以使用了。但请注意发布的示例代码中的错误,缺少 return 语句,应该是“return firebase.auth().signInWithCustomToken...”谢谢
2021-04-23 20:00:51
我知道serviceAccount is undefined这个套装在哪里?它包含什么?
2021-05-08 20:00:51
看起来您的最后一个问题发生在使用 protobufjs v6 的人身上。您可以尝试将 protobufjs v5 添加为依赖项吗?
2021-05-10 20:00:51