You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift & Firebase:iOS客户端如何检测令牌撤销并处理?

iOS客户端检测Google令牌撤销的实现方案

嘿,关于iOS客户端如何检测Google令牌被撤销这件事,我结合项目实践和Google的官方指南给你梳理清楚——毕竟之前做海外项目的时候踩过类似的坑,还算有发言权~

一、核心检测机制

Google针对令牌撤销的客户端响应,主要提供了被动监听和主动校验两种方式,搭配官方Sign-In SDK可以轻松实现:

1. 借助Google Sign-In SDK的内置监听

Google Sign-In for iOS SDK已经封装了令牌状态的监听逻辑,当令牌通过Admin SDK被撤销时,SDK会自动触发对应的回调:

  • 实现GIDSignInDelegate协议,通过didDisconnectWith回调捕获令牌撤销/用户断开的事件
  • 在didSignInFor回调中处理令牌失效的错误码(比如GIDSignInErrorCode.hasNoAuthInKeychain)

示例代码:

class GoogleAuthManager: NSObject, GIDSignInDelegate {
    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
        if let authError = error as NSError? {
            // 识别令牌撤销/失效的错误
            if authError.code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
                self.promptUserToReauthenticate()
            }
            return
        }
        // 登录成功后的逻辑:保存令牌、同步用户信息等
    }

    func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
        // 令牌被撤销、用户主动断开都会触发这个回调
        self.handleTokenRevocation()
    }

    // 辅助方法:提示用户重新认证
    private func promptUserToReauthenticate() {
        let alert = UIAlertController(title: "登录状态失效", message: "请重新登录以继续使用", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "去登录", style: .default) { _ in
            GIDSignIn.sharedInstance.signIn()
        })
        // 弹出alert(注意要获取当前ViewController)
        UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
    }

    // 处理令牌撤销的核心逻辑
    private func handleTokenRevocation() {
        // 1. 清除本地存储的所有令牌、用户信息
        GIDSignIn.sharedInstance.signOut()
        // 2. 终止当前敏感操作(比如正在发起的API请求)
        // 3. 引导用户重新登录
        self.promptUserToReauthenticate()
    }
}

2. 主动校验令牌有效性

在关键操作前(比如调用需要令牌授权的后端API、访问隐私数据),主动校验令牌状态是更稳妥的方式,避免依赖被动监听的延迟:

  • 使用SDK提供的refreshTokensIfNeeded方法,自动刷新并校验令牌;如果令牌已被撤销,该方法会返回错误
  • 也可以直接验证ID Token的有效性(比如检查签名、过期时间,或调用Google的令牌校验端点)

示例代码:

func callProtectedBackendAPI() {
    guard let currentUser = GIDSignIn.sharedInstance.currentUser else {
        self.promptUserToReauthenticate()
        return
    }

    // 主动刷新并校验令牌
    currentUser.refreshTokensIfNeeded { [weak self] refreshedUser, error in
        guard let self = self else { return }
        if let _ = error {
            // 令牌已失效/被撤销
            self.handleTokenRevocation()
            return
        }
        // 令牌有效,携带ID Token发起API请求
        guard let idToken = refreshedUser?.idToken?.tokenString else { return }
        self.performAPICall(withToken: idToken)
    }
}

// 发起后端API请求的方法
private func performAPICall(withToken token: String) {
    var request = URLRequest(url: URL(string: "你的后端API地址")!)
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    // 执行网络请求...
}

二、Google官方示例的核心思路

Google官方给出的最佳实践核心是:

结合被动监听和主动校验,在SDK自动捕获状态变化的同时,在敏感操作前主动验证令牌,确保一旦令牌被撤销,客户端能立即终止无效操作并引导用户重新认证。

这种方式既保证了实时性,又避免了因监听延迟导致的无效请求。

内容的提问来源于stack exchange,提问作者ktm125

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:42:20