如何使用Firebase Auth同步自定义声明令牌

q43xntqr  于 2023-03-31  发布在  其他
关注(0)|答案(2)|浏览(131)

我想使用Firebase自定义令牌来创建Firestore的规则,如下所示。

match /post/{postId}{
      allow create: if request.auth.token[role] == `admin`;
      allow read: if request.auth.token[role] == `admin`;   
 }

当一个用户注册一个应用程序时,我想使用云函数给予她一个角色。

const functions = require('firebase-functions');

export const updateAcl = functions
  .firestore.document("/members/{memberId}")
  .onCreate(async(user, context) => {
      await getAuth().setCustomUserClaims(user.uid, {role:'admin'});
  });

流动在这里。
1.用户注册了应用程序。
1.用户将在异步后端中被赋予一个角色。
1.使用自定义声明,内容将显示。
但这有个问题,因为时间的关系,当用户用后台的异步云功能得到角色的时候,内容已经出现了,第一次出现的时候,她还没有角色,我是说在内容出现之前,她应该有角色。
云函数onCreate现在没有同步,怎么解决?

t1qtbnec

t1qtbnec1#

自定义声明不会立即在规则中刷新,直到它们将自定义声明传播到客户端,您可以通过admin sdk调用setCustomUserClaims后,通过调用currentUser.getIdToken(true)在客户端上传播自定义声明来强制刷新ID令牌。
在自定义声明更改后,我所能想到的告诉客户端的是将数据写入firestore或rtdb:

export const initUser = functions
  .auth.user()
  .onCreate(async(user, context) => {
      await getAuth().setCustomUserClaims(user.uid, 'admin');
// Write data to database to tell user claims are changed then let client listen to this document.
  });

另一种选择,也是我更喜欢的一种,就是简单地使用firestore来实现基于角色的访问控制,你可以使用admin uid作为文档id,然后将这个文档写入一个集合调用admins,规则如下:

function isAdmin(){
  return exists(/databases/$(database)/documents/admins/$(request.auth.uid));
}

match /post/{postId}{
  allow create, read: if isAdmin();   
}
h79rfbju

h79rfbju2#

您可以使用beforeCreateblocking function。您需要将您的项目升级到Firebase Authentication with Identity Platform(它最多可免费使用50 K MAU IIRC)
你可以这样写你的函数:

export const initUser = functions
  .auth.user()
  .beforeCreate((user, context) => {
      return {
        customClaims: { admin: true }
      }
  });

Firebase文档中有一个示例
不要忘记在认证控制台注册你的阻止功能。(我不确定如果没有注册,它们的“非阻止”功能是否仍然有效,但如果你想阻止用户登录/注册,你肯定需要注册这个功能)

相关问题