如何使用 Firebase 身份验证在服务器端检索刷新令牌?
How can I retrieve the refresh token on the server-side using Firebase Authentication?
我需要为我的 Firebase 应用实施单设备浮动许可证,这样用户一次只能在一台设备上登录该应用。因此,当用户从另一台设备登录时,该用户的其他现有登录应该失效。
这是我正在考虑的流程:
- 登录后,从客户端发送 Firebase idToken 以在允许访问之前在服务器上进行验证
- 在服务器端,使用
verifyIdToken()
并为用户检索 refreshToken 并存储它
- 如果 refreshToken 已从先前为用户存储的值更改,使用
revokeRefreshTokens()
使其他刷新令牌无效
此方法的问题在于,目前从 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
。
我需要为我的 Firebase 应用实施单设备浮动许可证,这样用户一次只能在一台设备上登录该应用。因此,当用户从另一台设备登录时,该用户的其他现有登录应该失效。
这是我正在考虑的流程:
- 登录后,从客户端发送 Firebase idToken 以在允许访问之前在服务器上进行验证
- 在服务器端,使用
verifyIdToken()
并为用户检索 refreshToken 并存储它 - 如果 refreshToken 已从先前为用户存储的值更改,使用
revokeRefreshTokens()
使其他刷新令牌无效
此方法的问题在于,目前从 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
。