iOS第一个应用,接受hello world的不受信任证书
我正在制作一个基本的“hello world”iOS应用程序。我在云中有一个ubuntu服务器,我想从iOS应用程序中查询它。我理解服务器需要安全,即需要通过https请求访问,服务器上的证书需要“可信” 现在我要做的就是超越这个要求。我有一个在我的服务器上使用https的自签名证书。当我使用iOS应用程序发出请求时,它会给我一些关于iOS第一个应用,接受hello world的不受信任证书,ios,swift,http-post,Ios,Swift,Http Post,我正在制作一个基本的“hello world”iOS应用程序。我在云中有一个ubuntu服务器,我想从iOS应用程序中查询它。我理解服务器需要安全,即需要通过https请求访问,服务器上的证书需要“可信” 现在我要做的就是超越这个要求。我有一个在我的服务器上使用https的自签名证书。当我使用iOS应用程序发出请求时,它会给我一些关于nsurErrorFailingurPeerTrustErrorKey的错误信息,甚至有一行返回的消息说:NSLocalizedRecoverySuggestion
nsurErrorFailingurPeerTrustErrorKey
的错误信息,甚至有一行返回的消息说:NSLocalizedRecoverySuggestion=您是否仍要连接到服务器?
我知道这是一个常见的问题,在这个网站上有很多关于如何处理它的帖子。我尝试了一段来自的代码。我在代码中添加了以下内容:
func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust{
let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,credential);
}
}
我的整个ViewController代码如下:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, NSURLSessionDelegate {
// MARK: Properties
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var mealNameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Handle the text field’s user input through delegate callbacks.
nameTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
mealNameLabel.text = nameTextField.text
}
// MARK: Actions
@IBAction func setDefaultLabelText(sender: UIButton) {
mealNameLabel.text = "Default Text"
post_request()
}
func post_request(){
let request = NSMutableURLRequest(URL: NSURL(string: "https://54.164.XXX.XX/post_script.php")!)
request.HTTPMethod = "POST"
let postString = "id=13&name=Jack"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust{
let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,credential);
}
}
}
这个想法似乎是从连接中拾取
挑战
事件,并告诉它“是的,我想继续”。但这段代码似乎没有被调用。发送post请求,但我收到有关不受信任证书的错误消息。是否有人可以帮助我修复代码,以便我可以从服务器接受此证书?您不能使用共享会话获取这些委托方法。您必须实例化一个新的NSURLSession
,并将自己声明为代理
// Delegate methods won't be callend
let task = NSURLSession.sharedSession()...
// Use this to get delegate calls
let task = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
delegate: self,
delegateQueue: /* make a queue */)...
使用iOS 9,您还需要查看并将这些密钥添加到plist中。iOS 9中需要这些接口来允许SSL连接。您需要使ViewController
NSURLSessionDelegate
接收回调并将会话的委托设置为您的控制器,如下所示:
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
...
let task = session.dataTaskWithRequest(request) { data, response, error in
}
task.resume()
我对代表的含义仍有新的理解。你在这里是什么意思?/*排队*/。就像我的代码的上下文一样,我怎样才能将数据发布到我的IP,接受证书并获得响应呢?委托是一个实现特定方法的对象,对象将调用它。在此上下文中,您说没有调用方法
func-URLSession(\uu:task:didReceiveChallenge:completionHandler:)->Void)
。那是因为你不是代表。当您初始化该对象并将自己设置为委托时,该方法将被调用并接受证书,就像您在那里的代码一样。“生成队列”部分表示生成后台队列。或者如果你很懒,可以使用NSOperationQueue.mainQueue()
@keithbhunter抢先一步。应用程序传输安全也是一个有用的评论。我明白你在说什么,我正在努力理解。但是,在您的回答中,它在哪里显示了如何接受证书并从服务器获取响应?我已经在这里用您的代码行创建了会话,但它仍然因为证书而拒绝连接您接受证书的部分:completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,credential)
。检查AppTransportSecurity,如@keithbhunter所说,如果证书无效,这可能会阻止应用程序工作。仅供参考,我最终只购买了一个SSL证书,所有本机软件在任何解决方案下都能完美工作。