Firebase 自定义声明不会传播

Posted

技术标签:

【中文标题】Firebase 自定义声明不会传播【英文标题】:Firebase Custom Claims doesn't propagate 【发布时间】:2019-03-14 17:04:02 【问题描述】:

我正在使用 angularfire2 使用 Angular6 应用程序。我在用户创建中将角色设置为自定义声明,但它似乎没有传播。

当我创建用户时,我将用户 ID、业务 ID 和角色发送到云函数:

出价 > 业务 ID

角色>角色

req.body.uid > 用户标识

  const customClaims = 
    roles:  [bid]: urole 
  
  admin.auth().setCustomUserClaims(req.body.uid, customClaims)
    .then(result => 
      res
        .status(200)
        .send()
    )

问题是当对云函数的调用完成时,我想将用户重定向到需要用户设置自定义声明集的路由,但它失败了。经过一番调试,我发现如果运行:

this.angularFireAuth.auth.currentUser.getIdTokenResult(true).then(result => 
      return result.claims.roles
    )

调用云函数“result.claims.roles”后立即未定义,但如果我刷新页面,“result.claims.roles”有我之前设置的数据。

我已经尝试过 reload 方法和 getIdToken(true) 但我遇到了同样的问题。

有没有办法避免刷新页面并获得自定义声明?

谢谢!

【问题讨论】:

您能否在调用 HTTP 触发器端点的位置添加代码,然后获取结果?我只是想验证代码在调用getIDTokenResult(true) 之前是否等待结果。另外请务必将您的 SDK 更新到最新版本,因为 Cloud Firestore、Cloud Storage 和 RTDB 的规则过去仅在 uid 更改时更新,而不是在令牌更改时更新。 仁,这是我设置角色的电话:return this.http.post($this.environment.backendHostUrl/api/user/role, uid: userId, role: role, business: business ).pipe( catchError(error => of(console.log(error))) ).subscribe(response => debugger <--- I get: response = "null" ) 【参考方案1】:

当用户登录时,他们会获得一个有效期约为一小时的 ID 令牌。如果您设置自定义声明,他们的(服务器端)配置文件会立即更新,但他们的 ID 令牌不会自动更新。因此,您需要刷新他们的 ID 令牌才能获得新的自定义声明。

据我所知,此 ID 令牌仅在过期时通过调用 getIdTokenResult 进行刷新。如果是这个原因,调用 user.reload()然后 获取 ID 令牌应该会给您更新的声明。

【讨论】:

我已经做了这个修改,但我仍然没有得到之前设置的角色:return this.angularFireAuth.auth.currentUser.reload().then(() => return this.angularFireAuth.auth.currentUser.getIdTokenResult(true) ); 但是,如果我手动刷新页面,我会得到它们。 PS:我添加了 getIdTokenResult(true) 来强制刷新令牌。 嗯...我不确定为什么在这种情况下不起作用。对此感到抱歉。 在您从管理 SDK 设置自定义声明后,您需要强制刷新(传递 true)以确保最新声明是最新的。 嘿@bojeil。我们需要调用什么方法来强制刷新? OP 致电getIdTokenResult(true),这似乎并没有给他们新的声明。 这很奇怪。 getIdTokenResult(true) 应该强制刷新和更新最新的声明。除非用户最初使用自定义令牌登录。在这种情况下,自定义令牌声明将始终覆盖通过 admin sdk 设置的外部声明。【参考方案2】:

对我来说,它只是听取了其中一位 cmets 的建议:

// --------
// Frontend
// --------

// Triggering the cloud function
const url: string = 'url-to-your-cloud-function'
await this.http.post<unknown>(url, ).toPromise();


// After cloud function was run and custom claim was set -> refresh the id token
// The 'currentUser' is a reference to the firebase user
await this.authService.currentUser.getIdToken(true);

// --------
// Cloud Function - createSubscription
// --------

const createSubscription = () =>   
  await admin.auth().setCustomUserClaims(userId, 
    subscriber: true
  )


【讨论】:

以上是关于Firebase 自定义声明不会传播的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Auth Custom 声明未传播到客户端

Firebase 自定义声明 IOS 和 swift

Firebase - 自定义重置密码登陆页面

使用自定义声明导入 Firebase 用户

从 Flutter 为 Firebase 身份验证设置自定义声明

Firebase onCreate 向 auth.user 添加自定义声明