首页 > 解决方案 > 创建用户——React、Firebase 云函数

问题描述

我正在创建一个带有身份验证和使用 firebase 云功能的反应应用程序。我还使用 customClaims 设置用户角色,例如管理员、版主、编辑和用户。我还有一个 Firestore 文档,我在其中存储公司信息等用户信息,并且我有一个功能供管理员(我自己)创建其他用户。

但是,如果我想允许版主创建用户但只允许他们创建连接到他们自己公司的用户,我该怎么办。他们应该能够为自己的公司设置编辑甚至版主,但不能为另一家公司创建用户。

我知道我能够在客户端上直接根据加载给新用户的自己的用户配置文件传递用户信息。但这可能是一个安全问题,对吧?据我了解,最好的方法是在firebase云功能中自动添加信息?但是我需要同时访问我自己的凭据和新的用户凭据。这甚至可能吗?

exports.testfunc = (req, res) => {
const customClaims = {
  moderator: true,
  subscription: true
};
const newUser = {
    moderator: req.body.role,
    subscription: true,
    company: req.body.company //Want to set this one to the creators company. For example if my company is named Awsome inc then the new user gets the same. 
}

return admin
  .auth()
  .getUserByEmail(req.body.email)
  .then(userRecord => {
    db.doc(`/usr/${userRecord.uid}`).update(customClaims); //Updates the user doc
    return admin.auth().setCustomUserClaims(userRecord.uid, customClaims); //Setting the custom claims
  })
  .then(() => {
    console.log(`Successfully updated `);
    return res.status(201).json("Success");
  })
  .catch(err => {
    return res.status(500).json({ error: err.code });
  });

};

有没有更好的方法来实现这一目标?对这个问题有什么想法吗?

标签: reactjsfirebasereact-nativegoogle-cloud-firestoregoogle-cloud-functions

解决方案


您可以使用Callable Cloud Function而不是HTTPS Cloud Function 。使用可调用云功能“Firebase 身份验证和 FCM 令牌,如果可用,将自动包含在请求中”,如文档中所示。

因此,首先,每个用户都应该有一个拥有其公司名称价值的声明。

然后,在您的云函数中,您只需要阅读调用可调用云函数(即创建新用户)的主持人用户的声明并提取其公司名称。然后只需在新用户的相应“公司”声明中分配相同的公司名称即可。

因此,以下几行可以解决问题:

exports.createUser = functions.https.onCall(async (data, context) => {

  try {

        //Checking that the user calling the Cloud Function is authenticated
        if (!context.auth) {
            throw new Error('The user is not authenticated. Only authenticated Admin users can create new users.');
        }

        //Checking that the user calling the Cloud Function is a Moderator user
        const callerUid = context.auth.uid;  //uid of the user calling the Cloud Function
        const callerUserRecord = await admin.auth().getUser(callerUid);

        if (!callerUserRecord.customClaims.moderator) {
            throw new Error('Only Moderator users can create new users.');
        }

        const companyName = callerUserRecord.customClaims.companyName;

        //Use companyName to assign a Claim to the new user, as you do in your question
        const customClaims = {
          editor: true,  
          subscription: true,
          companyName: companyName
        };

        //....
        return ....

    } catch (error) {
            //....
            throw new functions.https.HttpsError('internal', error.message);

    }


});

您可能会对这篇文章感兴趣,该文章介绍了如何使用 Callable Cloud Function 构建一个模块,该模块允许具有特定管理员角色的最终用户创建其他用户(免责声明,我是作者)。all 概念与您的用例非常相似(它使用并详细解释了与上面相同的代码)。


推荐阅读