【问题标题】:How to set a 'Token xxxxxxxxxx' for 'Authorization' in HTTP header in URLSession如何在 URLSession 的 HTTP 标头中为“授权”设置“令牌 xxxxxxxxxx”
【发布时间】:2017-06-30 09:41:47
【问题描述】:

我正在使用的后端 API 需要在每个针对 HTTP 标头键 Authorization 的请求中发送一个令牌,格式为 Token xxxxxxxxxx

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

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

这有时会起作用,有时会在发送请求时剥离标头字段Authorization。我使用 Charles 代理检查了这一点。

Apple's documentation 声明如下。

NSURLSession 对象旨在处理 适合您的 HTTP 协议。因此,您不应修改 以下标头:授权、连接、主机、WWW-Authenticate

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

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

我不知道如何以及是否可以创建一个URLCredential 实例,该实例将为标题字段Authorization 添加Token xxxxxxxx

请有更多知识的人帮我解决这个问题?

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

编辑:

贴出相关代码。

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

在这里,我可以确认“授权”的标头字段已添加到请求的标头字典中。

但是,当我检查到达服务器的请求时,缺少“授权”的标头字段。有什么想法吗?

【问题讨论】:

  • request.addValue(value, forHTTPHeaderField: key) 根据我的经验工作可靠。我怀疑在“问题情况”中没有为请求调用您的代码。请发布更多相关代码来解决这个问题。
  • @shallowThought 我已经添加了相关代码。请看看你是否能发现我所做的事情有问题。

标签: ios swift nsurlsession nsurlsessionconfiguration


【解决方案1】:

我遇到了同样的问题,发现我缺少尾部斜杠 / 是问题所在。

服务器正在发回 301 Redirect 响应。 URLSession 自动跟随重定向,但也会删除 Authorization 标头。这可能是由于Authorization 的“特殊身份”。根据URLSessionConfigurationdocumentation

URLSession 对象旨在为您处理 HTTP 协议的各个方面。因此,您不应修改以下标头:

  • 授权
  • 连接
  • 主机
  • WWW-认证

如果需要Authorization 标头,请从URLSessionTaskDelegate 实现urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)。该方法在重定向时传递新请求,允许您添加回标头。

例如

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 与原始请求的域相同。为简洁起见,我将其从代码示例中省略了。

【讨论】:

  • 救命稻草……我以前也遇到过,但你帮我记住了。
猜你喜欢
  • 1970-01-01
  • 2021-06-20
  • 2013-07-07
  • 2015-05-26
  • 2016-08-04
  • 1970-01-01
  • 2021-02-13
  • 2021-03-03
  • 2013-01-21
相关资源
最近更新 更多