简体   繁体   中英

Authorization fails (cookes not sent) in URLSessionConfiguration.background with HTTPCookieStorage.shared

In my iOS app, I create a URLSession with default configuration:

// Part #1    
let urlSession = URLSession(configuration: .default)

The user logs in, the cookies are set and all API requests are Authorized and work fine. Now with the same cookies, I want to create a background URLSession for downloading large files from the same server.

// Part #2 
lazy var downloadsSession: URLSession = {
        let configuration = URLSessionConfiguration.background(withIdentifier:"x.bgSession")
        // Use cookies from shared storage
        configuration.httpCookieStorage = HTTPCookieStorage.shared
        return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    }()

The download request fails and the server returns Unauthorized . Using mitmproxy when I intercept this request, I notice that for downloadsSession , cookies are not set while making the HTTP download request.

However, now when I create a new ephemeral session, the Authorization works fine.

// Part #3
let sessionConfiguration = URLSessionConfiguration.ephemeral
        sessionConfiguration.httpCookieStorage = HTTPCookieStorage.shared
        session_ = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil);

What is the difference between Part #2 & Part #3 in terms of Authorization (setting cookies)? Why Part #3 succeeds while Part #2 fails?

for your part #1, #2, #3 add following line to request

request.httpShouldHandleCookies=true

If it still give you the same error consult your backend developer and check download permissions for file your trying to download

for complete help you may check following code

        let mainUrl = "your request url"
    request.httpMethod = serviceType
    request.httpShouldHandleCookies=true
    let cookie = HTTPCookie.requestHeaderFields(with: HTTPCookieStorage.shared.cookies(for: mainUrl as URL)!)
    request = setAccessToken_Cookie(request: request)
    request.allHTTPHeaderFields  = cookie
    var  session  = URLSession(configuration: URLSessionConfiguration.default)
    session = NetworkManager().configureURLSessionMethodWithDelegate(session: session)
    if downloadable
    {
        Downloader.downloadFile(url: mainUrl as URL, session: session, request:request, completion:  {
        })
    }





import Foundation
import UIKit

class Downloader:NSObject, URLSessionDownloadDelegate
{
    class func downloadFile(url: URL,session:URLSession, request:NSMutableURLRequest, completion: @escaping () -> ()) {
        var delegateSession = Downloader().configureURLSessionMethodDelegate(session: session)
        let downloads = delegateSession.downloadTask(with: request as URLRequest)
        downloads.resume()
    }
    func configureURLSessionMethodDelegate( session:URLSession) -> URLSession {
        var sessionWithDelegate = session
        sessionWithDelegate = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue:OperationQueue.main)
        return sessionWithDelegate
    }
     func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        guard let httpResponse = downloadTask.response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
                  print ("error : \(error according to your response code)")
                return
        }
        do {
            let documentsURL = try
                FileManager.default.url(for: .documentDirectory,
                                        in: .userDomainMask,
                                        appropriateFor: nil,
                                        create: false)
            let savedURL = documentsURL.appendingPathComponent(downloadTask.response?.suggestedFilename ?? "noname")
            print(location)
            print(savedURL)
            if FileManager.default.fileExists(atPath: savedURL.path)
            {
                AppUtility?.displayAlert(title: appName, messageText: "A file with same name already exist", delegate: nil)
            }
            else{
                try FileManager.default.copyItem(at: location, to: savedURL)
            }
        } catch {
            print ("file error: \(error)")
        }
    }
     func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
    {
        guard let httpResponse = downloadTask.response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
                print ("server error")
                return
        }
    }
     func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        DispatchQueue.main.async(execute: {  () -> Void in
            if(error != nil)
            {
                //handle the error
                print("Download completed with error: \(error!.localizedDescription)");

            }
        })
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM