Firebase多租户下调用setCustomUserClaims提示无对应用户记录如何解决
问题根源
默认的admin.auth()实例仅操作Firebase项目的全局用户池,Google Identity Platform多租户模式下的用户存储在对应租户的隔离资源池中,未指定租户ID的情况下,全局auth实例无法访问租户内的用户数据,因此会抛出用户不存在的报错。
解决方案
- 从ID Token解析得到的claims中提取租户ID,多租户登录后的token会自动携带
firebase.tenant字段存储当前用户所属租户ID - 通过Admin SDK的租户管理器获取对应租户的专属auth操作实例,所有租户侧用户的操作都通过该实例执行
修改后的核心代码示例
app.post("/setCustomClaims", async (req, res)=>{ const idToken = req.body; functions.logger.log("Here's idToken: ", idToken); // 验证ID token全局通用,不需要指定租户 const claims = await admin.auth().verifyIdToken(idToken); functions.logger.log("After verify ID Token"); // 提取租户ID并校验 const tenantId = claims.firebase?.tenant; if (!tenantId) { res.end(JSON.stringify({status: "invalid_tenant"})); return; } // 获取对应租户的auth操作实例 const tenantAuth = admin.auth().tenantManager().authForTenant(tenantId); if ( typeof claims.email !== "undefined" && typeof claims.email_verified !== "undefined" ) { functions.logger.log("Inside if condition"); functions.logger.log("Project ID is ", process.env.FIREBASE_CONFIG); // 改用租户auth实例查询用户 await tenantAuth.getUserByEmail(claims.email).then( (record) => functions.logger.log("Success: ", record)).catch( (reasonStr) => functions.logger.log("Rejected: ", reasonStr)); // 改用租户auth实例列用户 await tenantAuth.listUsers().then((users) => functions.logger.log("Users: ", users)); // 改用租户auth实例设置自定义声明 await tenantAuth.setCustomUserClaims(claims.sub, { youcanaccess: true, }); functions.logger.log("after setCustomClaims"); res.end(JSON.stringify({ status: "success", })); functions.logger.log("after success"); } else { res.end(JSON.stringify({status: "ineligible"})); functions.logger.log("after ineligible"); } });
注意事项
- 自定义声明会绑定到对应租户的用户身份上,客户端调用
getIdTokenResult()刷新token后即可读取到声明字段 - 跨租户的用户操作不允许,每个租户的auth实例仅能操作所属租户内的用户数据
内容的提问来源于stack exchange,提问作者handitan
相关产品推荐
相关产品推荐

