ios - 使用 HTTPCookieStorage.shared 在 URLSessionConfiguration.background 中授权失败(cookes 未发送)

标签 ios swift cookies urlsession nsurlsessionconfiguration

在我的 iOS 应用程序中,我使用默认配置创建一个 URLSession:

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

用户登录,设置 cookie,并且所有 API 请求都授权并且工作正常。现在,使用相同的 cookie,我想创建一个后台 URLSession,用于从同一服务器下载大文件。

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

下载请求失败,服务器返回未授权。使用mitmproxy当我拦截此请求时,我注意到对于 downloadsSession,在发出 HTTP 下载请求时未设置 cookie

但是,现在当我创建新的临时 session 时,授权工作正常。

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

第 2 部分和第 3 部分在授权(设置 cookie)方面有何区别?为什么第 3 部分成功而第 2 部分失败?

最佳答案

对于你的#1、#2、#3部分 添加以下行来请求

request.httpShouldHandleCookies=true

如果仍然出现相同的错误,请咨询您的后端开发人员并检查您尝试下载的文件的下载权限

要获得完整的帮助,您可以检查以下代码

        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)");

            }
        })
    }
}

关于ios - 使用 HTTPCookieStorage.shared 在 URLSessionConfiguration.background 中授权失败(cookes 未发送),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57651965/

相关文章:

iOS clang : error Xcode 7. 3.1

ios - foursquare 如何将其 map View 从表格标题动画化为全屏?

ios - 如何将应用程序移动到后台并在 selenium 中的同一驱动程序上打开另一个应用程序

ios - 仅在首次初始化自定义 UIView 时如何在 LayoutSubviews 中执行代码

ios - Swift 中两位小数之间的随机数

javascript - 在 Google Analytics 跟踪代码中设置安全参数

security - 编辑本地 cookie 值

ios - 使用 SceneKit 在 ARKit 中拖动 SCNNode

ios - Firebase 通知 : Send Message Through HTTP Post

javascript - 如何在 Web 浏览器中捕获 "JavaScript SetCookie event"?