Alamofire中Adapter执行完成后请求未发起问题求助
Alamofire Adapter中JWT认证后原请求未发起问题排查
问题场景
服务器采用JWT进行用户认证,无令牌时通过Alamofire的Adapter先获取新令牌,再发起原请求。已确认调用completion(.success(modifiedRequest)),但原请求未发出(经Proxyman验证)。
问题代码
lazy private(set) var tokenAdapter = Adapter { [weak self] request, session, completion in var modifiedRequest = request // Step1 if let accessToken = self?.credential.accessToken { let bearerToken = "Bearer \(accessToken)" modifiedRequest .addValue("Authorization", forHTTPHeaderField: bearerToken) completion(.success(modifiedRequest)) } else { // 从未获取过令牌的情况 guard let deviceId = self?.credential.devideIdentifier, let requestBox = self?.issueToken(deviceIdentity: DeviceIdentityDTO(imei: deviceId)) else { return completion(.failure(RequestGenerationError.crendentialIsNotAvailable)) } do { let issueTokenRequest = try requestBox.endPoint.toRequest() // Step2 session .request(issueTokenRequest) .responseDecodable(of: TokenResponse.self) { response in if let error = response.error { return completion(.failure(error)) } if let responseData = try? response.result.get().data { let accessToken = responseData.accessToken let refreshToken = responseData.refreshToken self?.credential.renewalTokens( accessToken: accessToken, refreshToken: refreshToken ) let bearerToken = "Bearer \(accessToken)" modifiedRequest .addValue("Authorization", forHTTPHeaderField: bearerToken) // Step3 return completion(.success(modifiedRequest)) } return completion(.failure(ResponseError.dataIsNotFound)) } } catch { completion(.failure(error)) } } }
排查与修复方案
核心问题:HTTP头字段添加参数顺序错误
Alamofire的URLRequest扩展方法addValue(_ value: String, forHTTPHeaderField field: String)参数顺序为值在前,字段名在后,但代码中完全写反了:
- 错误写法:
modifiedRequest.addValue("Authorization", forHTTPHeaderField: bearerToken) - 正确写法:
modifiedRequest.addValue(bearerToken, forHTTPHeaderField: "Authorization")
错误的参数顺序会导致添加一个名为Bearer xxxxxx的无效HTTP头,而非正确的Authorization: Bearer xxxxxx,这会触发Alamofire内部处理异常,直接导致原请求无法发起。
其他潜在问题修复
- 拼写错误修正:
devideIdentifier应为deviceIdentifier,若此字段为空会直接进入failure分支,阻断原请求。 - 线程安全处理:建议在主线程调用completion,避免异步回调线程问题:
DispatchQueue.main.async { completion(.success(modifiedRequest)) }
- 错误处理优化:
try? response.result.get()会吞掉错误,改为明确的错误捕获:
do { let tokenResponse = try response.result.get() guard let responseData = tokenResponse.data else { return completion(.failure(ResponseError.dataIsNotFound)) } // 后续令牌处理逻辑 } catch { return completion(.failure(error)) }
内容的提问来源于stack exchange,提问作者Choijun0
相关产品推荐
相关产品推荐

