URLSession不会在标头swift 4中传递"授权"键

San*_*osh 7 ios nsurlsession swift

我试图在URLRequest的标头中传递授权密钥.但是在服务器端没有收到密钥.从邮递员工作正常时调用相同的API.标头中的任何其他键工作正常,甚至授权密钥在服务器端也可见.

这是我的代码:

let headers = [
    "authorization": "token abcd"
]

var request = URLRequest.init(url: NSURL(string:
    "http://127.0.0.1:7000/api/channels?filter=contributed")! as URL)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = headers
let session = URLSession.init(configuration: config)

let dataTask = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
        print(error ?? "")
    } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse ?? "")
    }
})
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我尝试在会话配置和请求中设置令牌,但没有一个正在工作.

Wil*_*ard 6

这似乎正在工作:

// Set the security header
private var credentials: String {
    return "\(participantId):\(password)"
}

private var basicAuthHeader: String {
    return "Basic \(credentials)"
}

func getSettings(participantId: Int, password: String) -> Bool {

    self.participantId = participantId
    self.password = password

    let path = "/settings/\(participantId)"
    guard let url = URL(string: "\(BASE_URL)\(path)") else {
        Log.e("Invalid URL string, could not convert to URL")
        return false
    }

    var urlRequest = URLRequest(url: url)
    urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
    urlRequest.setValue(basicAuthHeader, forHTTPHeaderField: "Authorization")
    urlRequest.setValue(APP_FILE_NAME, forHTTPHeaderField: "User-Agent")

    // This is a synchronous wrapper extension around URLSession.dataTask()
    let (data, response, error) = URLSession.shared.synchronousDataTask(with: urlRequest)
    // Process the result...
}
Run Code Online (Sandbox Code Playgroud)

注意:我的同事编写的代码。谢谢约翰!

  • URLRequest 的官方文档指向[此页面](https://developer.apple.com/documentation/foundation/nsurlrequest#1776617),其中提到避免修改某些标头,例如“Authorization”。Apple 论坛上的[此线程](https://forums.developer.apple.com/thread/68809) 提供了一个使用委托回调来处理用户名/密码基本和摘要身份验证的示例。然而,对于承载令牌身份验证,[另一个线程](https://forums.developer.apple.com/thread/89811)建议没有客户端替代方案来修改 URLRequest `Authorization` 标头。 (2认同)

小智 0

我发现了同样的事情:设置标头字段授权并没有起到作用。

这是我确定的解决方案(效果很好):

我将 URLSessionDelegate 协议添加到当前的类中。不幸的是,这意味着继承自 NSObject。

然后,在定义 URLSession 时,我将其委托设置为“self”。

最后,我提供了一个身份验证质询处理程序。

在代码中,这一切看起来像:

public class SomeHTTPTask: NSObject, URLSessionDelegate {
    public init() {
        ... initialize variables ...
        super.init()
        ... now you are free to call methods on self ...
    }

    public func httpTask(withURL url: URL) {
        let request = URLRequest(url: url)
        ... set up request ...
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
        let task = session.dataTask(with: request) {data, response, error in
            ... now you have a result ...
        }
    }

    public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard let user = Credentials.sharedInstance.userId, let password = Credentials.sharedInstance.password else {
            completionHandler(.performDefaultHandling, nil)
            return
        }
        let userCredential = URLCredential(user: user,
                                           password: password,
                                           persistence: .permanent)
        completionHandler(.useCredential, userCredential)
    }

}
Run Code Online (Sandbox Code Playgroud)

希望这些细节是不言自明的。它只是一个提供凭据(如果可以的话)的身份验证质询处理程序。底层的 URLSession 将处理细节,无论它是 NTLM 或基本身份验证,还是诸如此类的事情。

最后,这似乎是一个可靠的解决方案。至少,它对我有用。

如果您喜欢阅读此类内容,这里有Apple 提供的一份很好的参考文档。