Swift中实现Bearer Token验证API请求及现有API代码正确性校验方法
问题解答
一、Bearer Token 逻辑存放建议
两种实现方式都可,如果你当前鉴权逻辑比较简单,且处于新手学习阶段,直接把Bearer Token相关逻辑写在现有的API Swift文件中即可,不需要额外新建文件。后续如果鉴权逻辑逐渐复杂(比如新增token过期自动刷新、token持久化存储、多接口统一鉴权拦截等需求),再单独拆分出鉴权管理类也完全来得及。
二、现有代码问题修复
你的代码存在几个明显的逻辑问题,需要先修复才能正常使用:
- 参数未生效问题:函数入参的
id和IMEI没有实际使用,endpoint里的查询参数是硬编码的,需要替换为动态传入的参数值 - 回调逻辑错误:JSON解码成功后,你错误的返回了
completed(.failure(.invalidData)),应该返回成功结果completed(.success(self.vehicles)) - 解码策略未生效:你创建了带
convertFromSnakeCase策略的decoder,但实际解码时又重新实例化了一个无配置的JSONDecoder(),导致驼峰转换规则没有生效 - HTTP请求限制问题:你的baseURL是HTTP协议,iOS默认禁止明文HTTP请求,需要在Info.plist中配置NSAppTransportSecurity的HTTP白名单,或者将接口升级为HTTPS协议
- 错误处理不友好:解码失败的catch分支可以打印error具体信息,方便调试排查问题,不需要所有错误都统一返回
invalidData
三、添加Bearer Token后的完整修改代码
static let shared = APICaller() private let baseURL = "http://000.000.000.000:3030/api/" // 这里可以替换为你实际存储token的方式,比如从Keychain读取,新手可以先存在UserDefaults private var bearerToken: String? { UserDefaults.standard.string(forKey: "saved_bearer_token") } private init() {} // 不需要全局存储vehicles的话可以删掉这个属性 var vehicles = [Vehicles]() func getVehicles(for id: String, IMEI: Int, completed: @escaping (Result<[Vehicles],Errors>) -> Void ){ // 动态拼接参数,不要硬编码 let endpoint = baseURL + "GetVehicle/?UserIdentificationValue=\(id)&IMEI=\(IMEI)" guard let url = URL(string: endpoint) else { completed(.failure(.invalidURL)) return } // 构建URLRequest添加Bearer Token头 var request = URLRequest(url: url) if let token = bearerToken { request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") } request.httpMethod = "GET" // 根据接口要求调整请求方法 let task = URLSession.shared.dataTask(with: request) { data, response, error in if let _ = error { completed(.failure(.unableToComplete)) return } guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { completed(.failure(.invalidResponse)) return } guard let data = data else { completed(.failure(.invalidData)) return } do { let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase // 用配置好的decoder解码 let vehicles = try decoder.decode([Vehicles].self, from: data) self.vehicles = vehicles DispatchQueue.main.async { // 解码成功返回正确结果 completed(.success(vehicles)) } } catch { // 调试阶段打印错误信息方便排查 print("解码失败:\(error)") completed(.failure(.invalidData)) } } task.resume() }
内容的提问来源于stack exchange,提问作者user17416997
相关产品推荐
相关产品推荐

