Swift中Firebase Authentication通过UID删用户:获取idToken解决INVALID_ID_TOKEN错误
我来帮你解决这个问题!要实现「Admin属性为true的用户可删除其他用户」的功能,核心是让管理员先获取自己的有效ID Token,再用这个Token去调用Firebase的删除账户API。下面是具体的Swift实现方案:
1. 先确认管理员身份并获取其ID Token
首先,当前登录的用户必须是标记为Admin的账号,我们需要先验证这一点,然后获取该管理员的最新ID Token(避免过期导致的INVALID_ID_TOKEN错误):
import FirebaseAuth // 检查当前用户是否是管理员,并获取其ID Token func getAdminIDToken(completion: @escaping (String?, Error?) -> Void) { guard let currentUser = Auth.auth().currentUser else { completion(nil, NSError(domain: "AuthError", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户未登录"])) return } // 这里假设你用Firebase自定义声明来标记管理员(也可以用用户属性,根据你的存储方式调整) currentUser.getIDTokenResult { tokenResult, error in if let error = error { completion(nil, error) return } guard let isAdmin = tokenResult?.claims["admin"] as? Bool, isAdmin else { completion(nil, NSError(domain: "AuthError", code: -2, userInfo: [NSLocalizedDescriptionKey: "当前用户不是管理员"])) return } // 获取管理员的有效ID Token currentUser.getIDToken { idToken, error in completion(idToken, error) } } }
2. 调用Firebase删除账户API
拿到管理员的ID Token后,就可以发起删除请求了。注意请求头里要带上这个Token做身份验证,请求体传入要删除用户的UID(localId字段):
import Foundation func deleteUser(withUID targetUID: String, apiKey: String, completion: @escaping (Error?) -> Void) { getAdminIDToken { adminIdToken, error in guard let adminIdToken = adminIdToken, error == nil else { completion(error) return } // 构建API请求URL let urlString = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/deleteAccount?key=\(apiKey)" guard let url = URL(string: urlString) else { completion(NSError(domain: "URLError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的API URL"])) return } // 构建请求体 let requestBody: [String: Any] = ["localId": targetUID] guard let httpBody = try? JSONSerialization.data(withJSONObject: requestBody) else { completion(NSError(domain: "DataError", code: -1, userInfo: [NSLocalizedDescriptionKey: "请求体序列化失败"])) return } // 构建请求 var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("Bearer \(adminIdToken)", forHTTPHeaderField: "Authorization") // 关键:用管理员的Token验证 request.httpBody = httpBody // 发起请求 let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { completion(error) return } guard let httpResponse = response as? HTTPURLResponse else { completion(NSError(domain: "ResponseError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的响应"])) return } // 处理响应状态码 switch httpResponse.statusCode { case 200: completion(nil) // 删除成功 case 400: // 解析错误信息,比如INVALID_ID_TOKEN、USER_NOT_FOUND等 if let data = data, let errorDict = try? JSONSerialization.jsonObject(with: data) as? [String: Any], let errorMessage = errorDict["error"] as? [String: Any], let message = errorMessage["message"] as? String { completion(NSError(domain: "FirebaseAPIError", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: message])) } else { completion(NSError(domain: "FirebaseAPIError", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: "请求失败"])) } default: completion(NSError(domain: "FirebaseAPIError", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: "请求失败,状态码:\(httpResponse.statusCode)"])) } } task.resume() } }
3. 使用示例
在需要删除用户的地方调用这个函数即可:
// 替换成你的Firebase API Key let myFirebaseAPIKey = "Your_Firebase_API_Key" // 要删除的用户UID let targetUserUID = "Target_User_UID" deleteUser(withUID: targetUserUID, apiKey: myFirebaseAPIKey) { error in if let error = error { print("删除失败:\(error.localizedDescription)") } else { print("用户删除成功!") } }
关键注意事项
- 管理员权限验证:我这里用了Firebase自定义声明(
admin字段)来标记管理员,你也可以根据自己的业务逻辑调整(比如从Firestore读取用户的Admin属性),但一定要确保只有授权用户能触发删除操作。 - ID Token有效性:每次删除前都要调用
getIDToken()获取最新的Token,避免Token过期导致INVALID_ID_TOKEN错误。 - API权限:确保你的Firebase项目中,「删除账户」的API权限是开放给管理员的——你可以在Firebase控制台的「Authentication」->「Sign-in method」->「API key restrictions」里配置,或者用Firebase Security Rules辅助验证。
内容的提问来源于stack exchange,提问作者Oleg
相关产品推荐
相关产品推荐

