云功能,删除Firestore子集合,是否需要AdminToken? [英] Cloud Functions, deleting Firestore SubCollections, is AdminToken necessary?

查看:61
本文介绍了云功能,删除Firestore子集合,是否需要AdminToken?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建可调用的云函数,当用户删除帖子时,它也会尝试删除评论,这是帖子的子集合.所以我看到了这个例子,并像一个文档例子一样实现了

const admin = require('firebase-admin');
const firebase_tools = require('firebase-tools');
const functions = require('firebase-functions');

admin.initializeApp({
  serviceAccountId: 'xxxxxx-xxxxx@appspot.gserviceaccount.com'
  }
);

exports.mintAdminToken = functions.https.onCall(async (data: any, context: any) => {
  const uid = data.uid;

  const token = await admin
    .auth()
    .createCustomToken(uid, { admin: true });

  return { token };
});

exports.recursiveDelete = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '2GB'
  })
  .https.onCall(async (data: any, context: any) => {
    // Only allow admin users to execute this function.
    if (!(context.auth && context.auth.token && context.auth.token.admin)) {
      throw new functions.https.HttpsError(
        'permission-denied',
        'Must be an administrative user to initiate delete.'
      );
    }

    const path = data.path;
    console.log(
      `User ${context.auth.uid} has requested to delete path ${path}`
    );

    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        yes: true,
        token: functions.config().fb.token
      });

    return {
      path: path 
    };
  });

,我成功将定制令牌接收到客户端.但是我现在要做什么?获得令牌后,我将其称为"recursiveDelete".来自客户端的功能,但发生错误PERMISSION_DENIED

  1. 是否应使用新的自定义管理员令牌来初始化接收令牌的用户? (如果我误会了,让我知道)
  2. 在删除这样的子集合时,真的需要管理令牌吗?它很难使用,所以我问.

解决方案

对于这种用例,我不认为您确实需要自定义令牌,我建议您使用Firebase Firestore规则,而不要实现自己的基于角色的身份验证

要遵循的步骤:

1-创建一个集合,您可以将其称为用户".并且在其中包括该用户可能具有的角色字段,例如"ADMIN".此集合中的每个文档ID都可以是firebase auth生成的用户的auth uid.您可以使用currentUser属性从前端获取此uid,并在此处进行解释

2-使用诸如以下的存储规则来保护您的数据库:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // only admins can remove posts
    match /posts/{postID} {
      allow read, write: if isAdmin();
    }

    // only admins can remove comments
    match /comments/{commentID} {
      allow read, write: if isAdmin();
    }

    // this function will check if the caller has an admin role and allow or disallow the task upon that
    function isAdmin() {
      return get(/databases/$(database)/documents/
          users/$(request.auth.uid)).data.role == "ADMIN";
   }

  }
}

3-现在,您确实不需要Firebase功能,并且可以从前端执行各种操作,Firestore角色将负责身份验证和授权.

一些使用JS进行数据处理的示例

I am trying to build callable cloud functions, when users delete a post, it also try to delete the comments, which is a sub-collection of the post. so I saw the example and implemented just like a documentation example

const admin = require('firebase-admin');
const firebase_tools = require('firebase-tools');
const functions = require('firebase-functions');

admin.initializeApp({
  serviceAccountId: 'xxxxxx-xxxxx@appspot.gserviceaccount.com'
  }
);

exports.mintAdminToken = functions.https.onCall(async (data: any, context: any) => {
  const uid = data.uid;

  const token = await admin
    .auth()
    .createCustomToken(uid, { admin: true });

  return { token };
});

exports.recursiveDelete = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '2GB'
  })
  .https.onCall(async (data: any, context: any) => {
    // Only allow admin users to execute this function.
    if (!(context.auth && context.auth.token && context.auth.token.admin)) {
      throw new functions.https.HttpsError(
        'permission-denied',
        'Must be an administrative user to initiate delete.'
      );
    }

    const path = data.path;
    console.log(
      `User ${context.auth.uid} has requested to delete path ${path}`
    );

    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        yes: true,
        token: functions.config().fb.token
      });

    return {
      path: path 
    };
  });

and I succeeded in receiving the custom token to the client. but what I have to do now? after getting token I called the "recursiveDelete" function from client but it occurs error PERMISSION_DENIED

  1. Should the user who received the token be initialized with a new custom admin token? (if I misunderstand let me know)
  2. Is the admin token really necessary when deleting a sub collection like this? It's difficult to use, so I ask.

解决方案

I don't think that you really need a custom token for this use case and I suggest that you use firebase firestore rules rather than implementing your own role based authentication.

Steps to follow:

1- create a collection that you may call "users" and include in it a field of the role that this user may have such as "ADMIN". every document id in this collection can be the auth uid of users that firebase auth generates. you can get this uid from your frontend by using the currentUser prop and it's all explained here

2- protect your database with firestore rules as such:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // only admins can remove posts
    match /posts/{postID} {
      allow read, write: if isAdmin();
    }

    // only admins can remove comments
    match /comments/{commentID} {
      allow read, write: if isAdmin();
    }

    // this function will check if the caller has an admin role and allow or disallow the task upon that
    function isAdmin() {
      return get(/databases/$(database)/documents/
          users/$(request.auth.uid)).data.role == "ADMIN";
   }

  }
}

3- now for this you really don't need a firebase function and you can do all kinds of operations from your frontend and Firestore roles will take care of the authentication and authorization.

some examples on data manipulation with JS

这篇关于云功能,删除Firestore子集合,是否需要AdminToken?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆