【发布时间】:2015-01-27 19:34:52
【问题描述】:
我在对我的 django rest api 执行 HTTPS 发布请求时遇到问题。我运行 django-sslserver 以在端口 8000 上公开 api。事情似乎很好,当我在浏览器中提出请求时 https://server-ip-addr:8000/api_view/ 我的浏览器抱怨“嘿!这家伙证书是自签名的!”我说“是的,我知道,那就是我”,然后继续做出危险的反应。
无论如何,我正在尝试在 Swift 中为 iOS 应用程序执行相同的操作。我从这个link here 中找到了关于实现NSURLSession 委托协议/功能NSURLSessionDelegate.URLSession() 和NSURLSessionTaskDelegate.URLSession()。我已经对示例进行了调整,以便它以原子方式对我的 sslserver 执行登录尝试。
我在下面的代码中这样做了,这是一个实现上述两种协议的类,旨在将用户名/密码凭据传递给服务器并等待响应。
class SecureLogin: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate {
func attemptLogin(username: String, password: String,
callback: ((NSData!,NSURLResponse!,NSError!) -> Void)?) {
println("inside attempt login")
var request = NSMutableURLRequest(URL: NSURL(string: "https://147.222.164.91:8000/ldapauth/")!)
request.HTTPMethod = "POST"
var params = ["username":username, "password":password] as Dictionary<String, String>
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration,
delegate: self,
delegateQueue:NSOperationQueue.mainQueue())
var task = session.dataTaskWithRequest(request,callback)
task.resume()
}
func URLSession(session: NSURLSession,
didReceiveChallenge challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition,NSURLCredential!) -> Void) {
println("Challenge received")
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust))
}
func URLSession(session: NSURLSession,
task: NSURLSessionTask,
willPerformHTTPRedirection response: NSHTTPURLResponse,
newRequest request: NSURLRequest,
completionHandler: (NSURLRequest!) -> Void) {
println("Redirection received")
var newRequest : NSURLRequest? = request
println(newRequest?.description)
completionHandler(newRequest)
}
}
所以我去尝试执行attemptLogin()函数,提供简单的回调函数来确认响应
var gatekeeper = SecureLogin()
gatekeeper.attemptLogin(username, password: password, callback: {data, response, error -> Void in
println("inside gatekeeper")
}
println("beginning wait")
sleep(25)
我让线程休眠 25 秒,以使进程保持足够长的时间以响应进来。
控制台上的输出如下:
内部尝试登录
开始等待
然后程序终止,没有收到响应/“内部看门人”消息,我的 django 服务器终端也没有显示任何收到的请求。我进行了健全性检查:我已经注释掉了委托方法的实现,服务器接收到请求,响应:
内部尝试登录
开始等待
2015-01-27 11:29:37.192 LdapAuthSecure[12783:1475994] NSURLConnection/CFURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9812)
没有处理授权质询的协议时的预期错误。
任何人都可以发现我的 NSURLSession 或其代表的实现有什么问题吗?我觉得很奇怪,请求甚至没有到达服务器。感谢您的帮助!
【问题讨论】:
标签: swift https django-rest-framework nsurlsession self-signed