如何在 URLSession 的 HTTP header 中为 'Authorization' 设置 'Token xxxxxxxxxx'

How to set a 'Token xxxxxxxxxx' for 'Authorization' in HTTP header in URLSession

我正在使用的后端 API 要求在针对 HTTP header 密钥 Authorization 的每个请求中发送令牌,格式为 - Token xxxxxxxxxx.

现在,我正在执行以下操作。

var getRequest = URLRequest(url: url)
getRequest.addValue("Token xxxxxxxx", forHTTPHeaderField: "Authorization")

这有时有效,有时有时有效,发送请求时 header 字段 Authorization 被删除。我使用 Charles 代理检查了这个。

Apple's documentation 说明如下。

An NSURLSession object is designed to handle various aspects of the HTTP protocol for you. As a result, you should not modify the following headers: Authorization, Connection, Host, WWW-Authenticate

作为此问题的解决方案,许多人建议对 URLSession 使用 didReceiveAuthenticationChallenge 委托方法。

在这里,您需要传递一个 URLSession.AuthChallengeDisposition 实例来告诉您要如何响应质询,并传递一个 URLCredential 实例来传递凭据以响应身份验证质询。

我不知道如何创建一个 URLCredential 实例来为 header 字段添加 Token xxxxxxxx Authorization.

有没有知识渊博的人帮我解决这个问题?

PS - 这个问题中提到的所有代码都在 Swift 3. This question 问的问题与我的类似。但是,那里给出的答案对我不起作用。而且,在有关 Apple 不允许添加 Authorization 的 header 的问题下提出的一些问题没有得到解答。

编辑:

发布相关代码。

var getRequest = URLRequest(url: url)
getRequest.httpMethod = "GET"
getRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
getRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let token = DataProvider.sharedInstance.token
getRequest.addValue("Token \(token)", forHTTPHeaderField: "Authorization")
let getTask = URLSession.shared.dataTask(with: getRequest) { (data, response, error) in
        if let data = data {
            print("--------GET REQUEST RESPONSE START--------")
            print("CODE: \((response as? HTTPURLResponse)?.statusCode ?? 0)")
            print("Response Data:")
            print(String(data: data, encoding: .utf8) ?? "")
            print("--------GET REQUEST RESPONSE END--------")
        }
}
getTask.resume()

在这里,我可以确认 'Authorization' 的 header 字段已添加到请求的 header 字典中。

但是,当我检查什么请求到达服务器时,'Authorization' 的 header 字段丢失了。有什么想法吗?

我 运行 遇到了这个完全相同的问题,发现我缺少尾部斜线 / 是问题所在。

服务器正在发回 301 Redirect 响应。 URLSession 自动跟随重定向,但也会删除 Authorization header。这可能是由于 Authorization 的 "special status"。根据 URLSessionConfigurationdocumentation:

An URLSession object is designed to handle various aspects of the HTTP protocol for you. As a result, you should not modify the following headers:

  • Authorization
  • Connection
  • Host
  • WWW-Authenticate

如果需要 Authorization header,请从 URLSessionTaskDelegate 实施 urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)。该方法通过重定向的新请求,允许您添加回 header.

例如

class APIClient: URLSessionTaskDelegate {
    let session: URLSession!
    initializeSession() {
        // Create a new session with APIClient as the delegate
        session = URLSession(configuration: URLSessionConfiguration.default,
                             delegate: self,
                             delegateQueue: nil)
    }

    // Perform the request
    func fetchRecords(handler: () => void) {
        var request = URLRequest(url: URL(string: "http://127.0.0.1:8000/api/employee/records")!)
        request.setValue(retrieveToken(), forHTTPHeaderField: "Authorization")
        session.dataTask(with: request, completionHandler: handler).resume()
    }

    // Implement URLSessionTaskDelegate's HTTP Redirection method
    func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
        // Create a mutable copy of the new request, add the header, call completionHandler
        var newRequest = request
        newRequest.addValue(retrieveToken(), forHTTPHeaderField: "Authorization")
        completionHandler(newRequest)
    }
}

重要提示!

盲目相信重定向是个坏主意。您应该确保您被重定向到的 URL 与原始请求的域相同。为简洁起见,我已将其从我的代码示例中删除。