我在对我的 django rest api 执行 HTTPS post 请求时遇到问题。我运行 django-sslserver 以在端口 8000 上公开 api。当我在浏览器 https://server-ip-addr:8000/api_view/
中发出请求时,一切似乎都很好我的浏览器提示“咦!这家伙的证书是自签名的!”我说“是的,我知道,那就是我”,然后继续做出危险的 react 。
无论如何,我正尝试在 Swift 中为 iOS 应用程序执行相同的操作。我从这个 link here 中找到了关于实现 NSURLSession
委托(delegate)协议(protocol)/函数 NSURLSessionDelegate.URLSession()
和 NSURLSessionTaskDelegate.URLSession()
。我已经调整了示例,以便它自动执行对我的 sslserver 的登录尝试。
我在下面的代码中这样做了,一个类实现了上面的两个协议(protocol),旨在将用户名/密码凭证传递给服务器并等待响应。
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 秒,以使进程保持事件状态足够长的时间,以便响应进入。
控制台输出如下:
inside attempt login
beginning wait
然后程序终止,没有收到响应/“内部网守”消息,我的 django 服务器终端也没有显示任何收到的请求。我运行了完整性检查:我注释掉了委托(delegate)方法的实现,服务器收到请求,响应:
inside attempt login
beginning wait
2015-01-27 11:29:37.192 LdapAuthSecure[12783:1475994] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9812)
没有处理授权挑战的协议(protocol)时的预期错误。
任何人都可以发现我的 NSURLSession 或其委托(delegate)的实现有任何问题吗?我觉得很奇怪,请求甚至没有到达服务器。感谢您的帮助!
最佳答案
如果这是 iOS 9,并且如果您是针对 iOS 9(或更高版本)SDK 构建您的应用程序,您还必须调整您的 Info.plist 文件以告诉它允许不安全的加载。否则,URL 加载系统将无法调用您的身份验证处理程序。
关于Swift NSURLSession HTTPS 自签名 - 请求永远不会到达服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28178537/