SwiftUI应用中Firebase Auth Revoke Token失效,如何启用Apple授权码流?
解决Firebase Apple登录授权码流未启用导致的
revokeToken错误 要解决你遇到的“Code flow is not enabled for Apple”错误,需要从Firebase控制台配置和客户端代码修改两方面启用授权码流,具体步骤如下:
一、Firebase控制台开启授权码流
- 打开Firebase控制台,进入你的项目的「Authentication」模块
- 切换到「登录方法」标签页,找到Apple登录选项并点击「编辑」
- 勾选「启用授权码流」,然后保存配置
- 若此前未完成Apple开发者后台配置,需先补充:在Apple Developer Portal创建对应服务ID,启用Sign In with Apple功能,将服务ID填入Firebase的Apple登录配置,并上传Apple生成的.p8私钥文件。
二、修改SwiftUI客户端的Apple登录代码
原来的Apple登录可能使用的是隐式流,现在需要调整为授权码流,核心是获取authorizationCode并传给Firebase:
- 生成并存储nonce(用于身份验证,和之前的隐式流逻辑一致):
private func randomNonceString(length: Int = 32) -> String { precondition(length > 0) let charset: [Character] = Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._") var result = "" var remainingLength = length while remainingLength > 0 { let randoms: [UInt8] = (0..<16).map { _ in var random: UInt8 = 0 let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random) if errorCode != errSecSuccess { fatalError("无法生成随机数:SecRandomCopyBytes失败,错误码\(errorCode)") } return random } randoms.forEach { random in if remainingLength == 0 { return } if random < charset.count { result.append(charset[Int(random)]) remainingLength -= 1 } } } return result }
- 发起Apple登录请求时,明确触发授权码返回:
func startAppleSignIn() { let nonce = randomNonceString() self.currentNonce = nonce // 存储nonce,后续验证用 let provider = ASAuthorizationAppleIDProvider() let request = provider.createRequest() request.requestedScopes = [.fullName, .email] // 关键:指定登录操作,让Apple返回授权码 request.requestedOperation = .operationLogin let controller = ASAuthorizationController(authorizationRequests: [request]) controller.delegate = self controller.presentationContextProvider = self controller.performRequests() }
- 在授权成功回调中,获取
authorizationCode并传给Firebase:
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else { return } // 提取身份令牌和授权码 guard let identityToken = appleIDCredential.identityToken, let idTokenString = String(data: identityToken, encoding: .utf8), let authorizationCode = appleIDCredential.authorizationCode, let codeString = String(data: authorizationCode, encoding: .utf8), let nonce = currentNonce else { print("无法获取Apple登录所需的令牌或授权码") return } // 创建Firebase OAuth凭证,传入授权码 let credential = OAuthProvider.credential(withProviderID: "apple.com", idToken: idTokenString, rawNonce: nonce, authorizationCode: codeString) // 登录Firebase Auth.auth().signIn(with: credential) { result, error in if let error = error { print("Firebase登录失败:\(error.localizedDescription)") return } // 登录成功后的业务逻辑,比如跳转主页 } }
三、调用revokeToken并删除账号
配置完成后,即可正常执行令牌撤销和账号删除逻辑:
func deleteUserAccount() { guard let currentUser = Auth.auth().currentUser else { return } Auth.auth().revokeToken { revokeError in if let revokeError = revokeError { print("撤销令牌失败:\(revokeError.localizedDescription)") return } // 令牌撤销成功,执行账号删除 currentUser.delete { deleteError in if let deleteError = deleteError { print("删除账号失败:\(deleteError.localizedDescription)") } else { print("账号删除成功,用户已退出") // 处理退出后的UI逻辑,比如返回登录页 } } } }
四、关键注意事项
- 确保Apple开发者后台的服务ID与Firebase配置的完全一致,且已启用Sign In with Apple
- Firebase的Apple登录配置必须上传有效的.p8私钥,否则授权码流无法正常工作
- Xcode项目需已添加「Sign In with Apple」Capability
- 测试时请使用真实Apple账号,部分模拟器环境可能无法正常触发授权码流
内容的提问来源于stack exchange,提问作者Jeff G
相关产品推荐
相关产品推荐

