我的 iOS 应用程序与 Firebase 身份验证集成,并提供 Google 登录功能。我观察到,我们的一些用户无法通过 Firebase Auth SDK 中的
getIDToken
(强制刷新 NO)检索 Firebase ID 令牌。
Domain: FIRAuthErrorDomain Code: 17021 NSLocalizedDescription: The user's credential is no longer valid. The user must sign in again.
有趣的是,(几乎)仅发生在通过 Google 登录的用户身上,而不会发生在使用电子邮件/密码或 Apple 登录的用户身上。
我对 ID 令牌的理解是,当我们通过 Firebase SDK 获取它时,如果当前 ID 令牌过期,它会在后台使用刷新令牌进行刷新(所以基本上它不会永远过期或持续很长时间,直到刷新令牌至少过期)。
我还阅读了这篇非常有用的文章。根据该文章,
Third-Party OAuth Access Tokens
(在本例中为 Google OAuth access token
?)不用于向 Firebase 进行身份验证,因此其过期很可能不是问题的原因。
您知道为什么会发生这种情况,尤其是仅在 Google 登录中吗?例如,Google 登录的刷新令牌是否可能是短暂的?
我从来没有找到根本原因,但我最终发现它已经通过重新获取ID令牌强制刷新来解决,当由于过期原因而失败时,如下所示。
- func getIdToken() async throws -> String {
+ func getIdToken(forcingRefresh: Bool = false) async throws -> String {
guard let currentUser = Auth.auth().currentUser else {
throw AuthenticationServiceError.unauthenticated
}
do {
- return try await currentUser.getIDToken()
+ return try await currentUser.getIDTokenResult(forcingRefresh: forcingRefresh).token
} catch {
+ // Retry to get ID token forcing refresh to see if it solves the token expiration problem observed many in production.
+ if let error = error as? AuthErrorCode, error.code == .userTokenExpired && !forcingRefresh {
+ return try await getIdToken(forcingRefresh: true)
+ }
throw error
}
}