如何从 Swift 中的 URLSession 响应中获取 cookie

How to get cookies from URLSession response in Swift

第一次提问

我正在使用 Swift 5. 我正在制作一个 log-in 功能,所以我需要使用 Cookie 保存 "JSESSIONID",所以我试图从响应 header 的 Set-Cookie 参数中读取数据,但是我无法获得任何数据。如何获取数据?

我检查过 "Set-Cookie" 是由 servlet 使用 curl 命令发送的。我附上了回复 header.

jun-MacBook-Pro:~ junki-t$ curl -X POST -D - -d "SOME PARAMETERS" http://example.com/PATH/UserProfilingService
HTTP/1.1 302 Found
Date: Tue, 23 Jul 2019 10:49:02 GMT
Set-Cookie: JSESSIONID=91********************BA; Path=/******; HttpOnly
Location: /?AUTHORIZED=yes&USERPROFILEKEY=*********
Content-Length: 0
Connection: close
Content-Type: text/plain

jun-MacBook-Pro:~ junki-t$ 

我试图在 Swift 应用程序中转储响应数据,但是 "Set-Cookie" 没有找到。

- some: <NSHTTPURLResponse: 0x281050860> { URL: http://example.com/?AUTHORIZED=yes&USERPROFILEKEY=********* } { Status Code: 200, Headers {
    "Accept-Ranges" =     (
        bytes
    );
    Connection =     (
        close
    );
    "Content-Length" =     (
        146
    );
    "Content-Type" =     (
        "text/html"
    );
    Date =     (
        "Wed, 17 Jul 2019 08:51:38 GMT"
    );
    Etag =     (
        "\"92-5********a3\""
    );
    "Last-Modified" =     (
        "Wed, 30 Nov 2016 07:44:17 GMT"
    );
    Server =     (
        Apache
    );
} } #0
    - super: NSURLResponse
      - super: NSObject
func tryAuth() {
    let id = "*****"
    let pass = "*****"

    let url = URL(string: "<Some url>")
    var url_request = URLRequest(url: url!)
    url_request.httpMethod = "POST"
    url_request.httpShouldHandleCookies = true

    let body = "SOME PARAMETERS FOR AUTHENTICATE"
    url_request.httpBody = body.data(using: String.Encoding.utf8)

    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
    session.configuration.httpCookieAcceptPolicy = .always
    session.configuration.httpCookieStorage = HTTPCookieStorage.shared
    session.configuration.httpShouldSetCookies = true

    session.dataTask(with: url_request).resume()
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
    let httpResponse = response as? HTTPURLResponse
    var dict = httpResponse?.allHeaderFields
    let cookies = HTTPCookie.cookies(withResponseHeaderFields: httpResponse?.allHeaderFields as! [String : String], for: response.url!)
    dump(cookies) // for testing.
    //
    // some process to get/save cookie.
    //
}

我认为cookies有一些数据(我想得到"JSESSIONID"),但是cookies有0个元素。

所以我无法获取任何 cookie 数据。

来自 HTTPCookieAcceptPolicy 文档:

This property determines the cookie accept policy for all tasks within sessions based on this configuration. The default value is NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain. You can change it to any of the constants defined in the NSHTTPCookieAcceptPolicy enumerated type. If you want more direct control over what cookies are accepted, set this value to NSHTTPCookieAcceptPolicyNever and then use the allHeaderFields and cookiesWithResponseHeaderFields:forURL: methods to extract cookies from the URL response object yourself.

因此,您需要设置session.configuration.httpCookieAcceptPolicy = .never,或者如果您希望系统自动设置cookie,您可以使用HTTPCookieStorage.shared.cookies(for: response.url)