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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:06:18