Alamofire SessionManager中JWT请求头动态更新问题
解决Alamofire SessionManager无法获取最新JWT的问题
这个问题我之前也踩过坑!核心原因是你的Almgr作为懒加载单例,初始化时只把JWT写入了URLSessionConfiguration的httpAdditionalHeaders一次,之后这个配置里的请求头不会自动跟着UserDefaults的变化更新。要实现每次请求都用最新的JWT,这里有几个靠谱的解决方案:
方案一:每次请求手动注入最新JWT
最直接的方式,发起请求时手动添加Authorization头,覆盖SessionManager的默认值:
func makeTargetRequest(url: String) { guard let jwt = UserDefaults.standard.string(forKey: conf.JWT_KEY) else { // 处理JWT不存在的异常情况 return } let customHeaders: HTTPHeaders = [ "Authorization": "Bearer \(jwt)", "Accept": "application/json" ] Almgr.request(url, headers: customHeaders).responseJSON { response in // 处理请求响应逻辑 } }
优点是简单直观,不需要改动原有SessionManager的初始化代码;缺点是每次发起请求都要重复写头处理逻辑,代码冗余度较高。
方案二:同步更新SessionManager的配置头
每次更新UserDefaults里的JWT时,同步修改Almgr配置中的请求头:
// 更新JWT时调用这个方法 func updateCurrentJWT(_ newJWT: String?) { UserDefaults.standard.set(newJWT, forKey: conf.JWT_KEY) UserDefaults.standard.synchronize() // 同步更新SessionManager的请求头 var updatedHeaders = Alamofire.SessionManager.defaultHTTPHeaders updatedHeaders["Authorization"] = "Bearer \(newJWT ?? "")" updatedHeaders["Accept"] = "application/json" Almgr.session.configuration.httpAdditionalHeaders = updatedHeaders }
这种方式能保证后续请求自动使用最新JWT,不过要注意URLSessionConfiguration的httpAdditionalHeaders是线程安全的,Alamofire内部已经做了相关处理,不用担心多线程问题。
方案三:使用Alamofire的RequestAdapter(推荐)
这是Alamofire官方推荐的动态修改请求的方案,扩展性强,适合复杂的请求头管理场景:
- 先定义一个遵循
RequestAdapter协议的JWT适配器:
class JWTRequestAdapter: RequestAdapter { func adapt(_ urlRequest: URLRequest) throws -> URLRequest { var adaptedRequest = urlRequest guard let latestJWT = UserDefaults.standard.string(forKey: conf.JWT_KEY) else { return adaptedRequest } // 注入最新JWT和固定请求头 adaptedRequest.setValue("Bearer \(latestJWT)", forHTTPHeaderField: "Authorization") adaptedRequest.setValue("application/json", forHTTPHeaderField: "Accept") return adaptedRequest } }
- 修改你的
Almgr初始化代码,添加这个适配器:
var Almgr : Alamofire.SessionManager = { // 服务器信任策略配置 let serverTrustPolicies: [String: ServerTrustPolicy] = [ "localhost": .disableEvaluation ] // 创建默认配置 let configuration = URLSessionConfiguration.default configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders let manager = Alamofire.SessionManager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) // 绑定JWT适配器 manager.adapter = JWTRequestAdapter() return manager }()
这样每次Almgr.request发起请求前,都会自动调用适配器的adapt方法,注入最新的JWT到请求头中,完美解决你的问题,后续如果要添加其他动态请求头也能轻松扩展。
个人强烈推荐方案三,它更符合Alamofire的设计理念,代码也更整洁易维护。
内容的提问来源于stack exchange,提问作者Sankar
相关产品推荐
相关产品推荐

