Search code examples
iosswiftalamofire

Reqeust doesn't proceed when adpater finished it's work in Alamofire


I have trouble about using http request with Alamofire my sever uses JWT to authenticate user. so when JWT doesn't exist request have to create one. so I do this job in Adapter in Alamofire

step 1. check tokens are in memory step 2. if not exists reqeust new token to server (new request) step 3. got token and calls completion(.success( request with token ))

problem is that, although step3 is finished well, request doesn't work (I checked that request doen't made in Proxyman)

I don't get what is wrong.. help me please

below code is my adapter


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))
        }
    }
}

It was confirmed that the request did not start after calling the Adapter's completion closure.


Solution

  • It seems like the issue is with how the Authorization header is being added to the request. Instead of modifiedRequest.addValue("Authorization", forHTTPHeaderField: bearerToken), it should be modifiedRequest.addValue(bearerToken, forHTTPHeaderField: "Authorization"). Here's the corrected adapter code:

    here's code you should try if this works for u

    lazy private(set) var tokenAdapter = Adapter { [weak self] request, session, completion in
        
        var modifiedRequest = request
        
        // Step 1
        if let accessToken = self?.credential.accessToken {
            
            let bearerToken = "Bearer \(accessToken)"
            
            modifiedRequest.addValue(bearerToken, forHTTPHeaderField: "Authorization")
            
            completion(.success(modifiedRequest))
            
        } else {
            
            // No token issued previously
            guard let deviceId = self?.credential.deviceIdentifier,
                  let requestBox = self?.issueToken(deviceIdentity: DeviceIdentityDTO(imei: deviceId))
            else {
                return completion(.failure(RequestGenerationError.credentialIsNotAvailable))
            }
        
            do {
                let issueTokenRequest = try requestBox.endPoint.toRequest()
                    
                // Step 2
                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(bearerToken, forHTTPHeaderField: "Authorization")
                            
                            // Step 3
                            return completion(.success(modifiedRequest))
                        }
                        
                        return completion(.failure(ResponseError.dataIsNotFound))
                    }
                
            } catch {
                completion(.failure(error))
            }
        }
    }
    

    The main correction is in the line modifiedRequest.addValue(bearerToken, forHTTPHeaderField: "Authorization"). This should fix the issue with the request not proceeding after the adapter's completion closure is called.