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

iOS GIDSignIn SDK V6.0.2:restorePreviousSignIn()不刷新过期idToken求实现

解决Google登录restorePreviousSignIn返回过期idToken的问题

你的问题核心在于:restorePreviousSignIn() 仅从本地缓存恢复用户的登录状态,不会自动检测并刷新过期的idToken。要解决这个问题,需要在恢复登录后主动检查令牌有效性,若过期则触发刷新流程。

以下是修正后的完整实现代码:

GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
    if let error = error, user == nil {
        print("无法恢复之前的登录会话,错误:\(error.localizedDescription)")
        // 此处可引导用户重新登录
        return
    }
    
    guard let currentUser = user else {
        print("无已保存的登录用户")
        return
    }
    
    // 检查当前用户的认证信息及idToken
    guard let auth = currentUser.authentication, let idToken = auth.idToken else {
        print("用户认证信息无效,需重新登录")
        return
    }
    
    // 解析idToken中的过期时间(JWT格式的payload包含exp字段)
    if let payloadData = idToken.components(separatedBy: ".").dropFirst().first?.base64DecodedData(),
       let payload = try? JSONSerialization.jsonObject(with: payloadData, options: []) as? [String: Any],
       let expTimestamp = payload["exp"] as? TimeInterval {
        let expirationDate = Date(timeIntervalSince1970: expTimestamp)
        let currentDate = Date()
        
        // 令牌已过期,触发刷新
        if currentDate >= expirationDate {
            currentUser.authentication.refreshTokensIfNeeded { refreshedAuth, error in
                if let error = error {
                    print("刷新令牌失败:\(error.localizedDescription)")
                    // 刷新失败时引导用户重新登录
                    return
                }
                
                guard let newAuth = refreshedAuth, let newIdToken = newAuth.idToken else {
                    print("刷新后未获取到有效令牌")
                    return
                }
                
                // 使用新的idToken执行后续逻辑
                print("获取到新的idToken:\(newIdToken)")
            }
        } else {
            // 令牌仍有效,直接使用原idToken
            print("当前idToken仍有效:\(idToken)")
            // 执行业务逻辑
        }
    } else {
        // 无法解析过期时间时,直接尝试刷新令牌
        currentUser.authentication.refreshTokensIfNeeded { refreshedAuth, error in
            if let error = error {
                print("刷新令牌失败:\(error.localizedDescription)")
                return
            }
            
            guard let newAuth = refreshedAuth, let newIdToken = newAuth.idToken else {
                print("刷新后未获取到有效令牌")
                return
            }
            
            print("获取到新的idToken:\(newIdToken)")
            // 使用新令牌
        }
    }
}

// 扩展方法:处理JWT的URL安全Base64解码
extension String {
    var base64DecodedData: Data? {
        let padded = self.padding(toLength: ((self.count + 3) / 4) * 4, withPad: "=", startingAt: 0)
        let base64EncodedString = padded.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
        return Data(base64Encoded: base64EncodedString)
    }
}

关键说明

  • 令牌过期检查:通过解析JWT格式idToken的exp字段(过期时间戳),判断当前时间是否已超过令牌有效期。
  • 主动刷新逻辑:调用refreshTokensIfNeeded()方法,该方法会自动判断令牌是否需要刷新,若需要则向Google服务器请求新的有效令牌。
  • 异常 fallback:即使无法解析过期时间,也会触发刷新流程,确保能获取到可用的idToken。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:07:25