如何使用 Firebase 身份验证在服务器端检索刷新令牌?

How can I retrieve the refresh token on the server-side using Firebase Authentication?

我需要为我的 Firebase 应用实施单设备浮动许可证,这样用户一次只能在一台设备上登录该应用。因此,当用户从另一台设备登录时,该用户的其他现有登录应该失效。

这是我正在考虑的流程:

  1. 登录后,从客户端发送 Firebase idToken 以在允许访问之前在服务器上进行验证
  2. 在服务器端,使用 verifyIdToken() 并为用户检索 refreshToken 并存储它
  3. 如果 refreshToken 已从先前为用户存储的值更改,使用 revokeRefreshTokens()
  4. 使其他刷新令牌无效

此方法的问题在于,目前从 Firebase Admin SDK 中的 verifyIdToken() 返回的 DecodedIdToken 对象没有 refreshToken可用。并且 revokeRefreshTokens() 不接受指定为用户撤销哪些刷新令牌。默认情况下,它会撤销用户的所有刷新令牌。

另一点需要注意的是,虽然 refreshToken 在客户端的 User 对象中可用,但我们无法发送这直接发送到服务器端,因为它可以在客户端进行操作以从多个设备发送相同的 refreshToken,这会破坏目的。更好的方法是发送具有有限到期时间的 idToken

那么,关于如何使用 Firebase 身份验证一次仅在一台设备上实施主动登录,是否还有其他替代方案/建议?

出于正确的原因,您无法从 ID 令牌中获取 refreshToken。否则没有意义,如果它是从 idToken 中检索到的。

使用 revokeRefreshTokens 实现单个会话也很困难,因为这将撤销所有现有会话并且对于防止令牌盗窃更有用,而不是会话管理。

您可以执行以下操作。每次将 ID 令牌发送到您的服务器时,从解码的令牌中解析 auth_time 并跟踪它(您将保存最新的)。那是一个会话的认证时间。从同一个 refreshToken 生成的所有 idTokens 将具有相同的 auth_time。您将始终跟踪最新的 auth_time,并且只要您获得带有更旧的 auth_time 的 ID 令牌,就认为该会话已撤销并阻止对该会话的访问。当这种情况发生时,您可以 return 一条错误消息来强制 signOut