Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift 3 HTTPS获取请求_Ios_Swift_Ssl_Https - Fatal编程技术网

Ios Swift 3 HTTPS获取请求

Ios Swift 3 HTTPS获取请求,ios,swift,ssl,https,Ios,Swift,Ssl,Https,您好,我正在尝试从HTTPS url执行get请求。但是我不断地犯错误 生成器文件。 2017-10-13 18:13:43.403238+0800 VQ智能家居[13412:2155471]TIC SSL信任错误[6:0x604000167680]:3:0 2017-10-13 18:13:43.403672+0800 VQ智能家居[13412:2155471]NSURLSession/NSURLConnection HTTP加载失败 (kCFStreamErrorDomainSSL,-981

您好,我正在尝试从HTTPS url执行get请求。但是我不断地犯错误

生成器文件。 2017-10-13 18:13:43.403238+0800 VQ智能家居[13412:2155471]TIC SSL信任错误[6:0x604000167680]:3:0 2017-10-13 18:13:43.403672+0800 VQ智能家居[13412:2155471]NSURLSession/NSURLConnection HTTP加载失败 (kCFStreamErrorDomainSSL,-9813) 2017-10-13 18:13:43.404000+0800 VQ智能家居[13412:2155471]任务。HTTP加载失败(错误) 代码:-1202[3:-9813]) 2017-10-13 18:13:43.404496+0800 VQ智能家居[13412:2155472]任务。已完成,但出现错误-代码: -1202 error=可选(error Domain=NSURLErrorDomain Code=-1202“此服务器的证书无效。您可能正在连接到 假装为“202.73.46.176”的服务器可能会 有风险的机密信息。” UserInfo={nSurlerErrorFailingUrlPeerTrustErrorKey=,NSLocalizedRecoverySuggestion=您想 是否仍要连接到服务器?,kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813,NSErrorPeerCertificateChainKey=( "" ),NSUnderlyingError=0x60400025c920{Error Domain=KCferrordomaincfn网络代码=-1202“(空)” UserInfo={kCFStreamPropertySSLClientCertificateState=0, KCFStreamPropertySLpeertrust=, _KCFnetworkCfStreamsSrorOriginalValue=-9813,kCFStreamErrorDomainKey=3,kCFStreamErrorCodeKey=-9813,KCFStreamPropertySLpeerCertificates=( "" )}},NSLocalizedDescription=此服务器的证书无效。您可能正在连接到一个假装是的服务器 “202.73.46.176”可以将您的机密信息放在 风险。, NSErrorFailingURLKey=, NSErrorFailingURLStringKey=, NSErrorClientCertificateStateKey=0})

ViewdidLoad

let urlstr: String = "https://202.73.46.176/api/v1/user/find/all/1"

let request = NSMutableURLRequest(url: NSURL(string: urlstr)! as URL)
request.httpMethod = "GET"
let postString = ""
request.httpBody = postString.data(using: String.Encoding.utf8)

let task = URLSession.shared.dataTask(with: request as URLRequest) {
    data, response, error in
    if error != nil {
        print("error=\(error)")
        return
    }
    print("response = \(response)")

    let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
    print("responseString = \(responseString)")
}
task.resume()
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        //Implementation 1: VERY WEAK METHOD
        /*if challenge.previousFailureCount > 0{
         completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
         }else{
         completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:challenge.protectionSpace.serverTrust!))
         }*/

        //Implementation 2:
        var disposition: URLSession.AuthChallengeDisposition = URLSession.AuthChallengeDisposition.performDefaultHandling
        var credential:URLCredential?

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            //certificate-based server credentials are used when verifying the server’s identity
            credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)

            if (credential != nil) {
                disposition = URLSession.AuthChallengeDisposition.useCredential
            }
            else{
                disposition = URLSession.AuthChallengeDisposition.performDefaultHandling
            }
        }
        else{
            disposition = URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge
        }
        print("==============", #function,"  disposition: ", disposition)
        print("==============", #function,"  disposition: ", credential!)

        //completionHandler(disposition, credential);




        //Implementation 3:
        let serverTrust = challenge.protectionSpace.serverTrust
        let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)

        // Set SSL policies for domain name check
        let policies = NSMutableArray();
        policies.add(SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))
        SecTrustSetPolicies(serverTrust!, policies);

        // Evaluate server certificate
        var result = SecTrustResultType(rawValue: 0)!
        SecTrustEvaluate(serverTrust!, &result)

        let isServerTrusted:Bool = (result == SecTrustResultType.unspecified || result == SecTrustResultType.unspecified || result == SecTrustResultType.proceed)
        print("==============",#function,"  isServerTrusted: ", isServerTrusted)
        print("==============", #function,"  result: ", result.hashValue,"  SecTrustResultType.unspecified: ", SecTrustResultType.unspecified.hashValue,"  SecTrustResultType.proceed: ", SecTrustResultType.proceed.hashValue)
        var certName = ""
//        if self.isSimulatingCertificateCorruption {
//            certName = corruptedCert
//        } else {
//            certName = cert
//        }

        // Get local and remote cert data
        let remoteCertificateData = SecCertificateCopyData(certificate!) as Data
        let pathToCert            = Bundle.main.path(forResource: certName, ofType: "der")
        let localCertificate      = try! Data(contentsOf: URL(fileURLWithPath: pathToCert!))
        print(" remoteCertificateData: ", remoteCertificateData,"       localCertificate: ", localCertificate, "       serverTrust: ", serverTrust.debugDescription  )

        if ( remoteCertificateData == localCertificate) { //TODO:- this is strictly for tesing puposes, to allow untrusted severs. REMOVE IN PRODUCTION.
            let credential:URLCredential = URLCredential(trust: serverTrust!)
            completionHandler(.useCredential, credential)
        }else if (isServerTrusted && (remoteCertificateData == localCertificate)) {
            let credential:URLCredential = URLCredential(trust: serverTrust!)
            completionHandler(.useCredential, credential)
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
方法

let urlstr: String = "https://202.73.46.176/api/v1/user/find/all/1"

let request = NSMutableURLRequest(url: NSURL(string: urlstr)! as URL)
request.httpMethod = "GET"
let postString = ""
request.httpBody = postString.data(using: String.Encoding.utf8)

let task = URLSession.shared.dataTask(with: request as URLRequest) {
    data, response, error in
    if error != nil {
        print("error=\(error)")
        return
    }
    print("response = \(response)")

    let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
    print("responseString = \(responseString)")
}
task.resume()
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        //Implementation 1: VERY WEAK METHOD
        /*if challenge.previousFailureCount > 0{
         completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
         }else{
         completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:challenge.protectionSpace.serverTrust!))
         }*/

        //Implementation 2:
        var disposition: URLSession.AuthChallengeDisposition = URLSession.AuthChallengeDisposition.performDefaultHandling
        var credential:URLCredential?

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            //certificate-based server credentials are used when verifying the server’s identity
            credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)

            if (credential != nil) {
                disposition = URLSession.AuthChallengeDisposition.useCredential
            }
            else{
                disposition = URLSession.AuthChallengeDisposition.performDefaultHandling
            }
        }
        else{
            disposition = URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge
        }
        print("==============", #function,"  disposition: ", disposition)
        print("==============", #function,"  disposition: ", credential!)

        //completionHandler(disposition, credential);




        //Implementation 3:
        let serverTrust = challenge.protectionSpace.serverTrust
        let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)

        // Set SSL policies for domain name check
        let policies = NSMutableArray();
        policies.add(SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))
        SecTrustSetPolicies(serverTrust!, policies);

        // Evaluate server certificate
        var result = SecTrustResultType(rawValue: 0)!
        SecTrustEvaluate(serverTrust!, &result)

        let isServerTrusted:Bool = (result == SecTrustResultType.unspecified || result == SecTrustResultType.unspecified || result == SecTrustResultType.proceed)
        print("==============",#function,"  isServerTrusted: ", isServerTrusted)
        print("==============", #function,"  result: ", result.hashValue,"  SecTrustResultType.unspecified: ", SecTrustResultType.unspecified.hashValue,"  SecTrustResultType.proceed: ", SecTrustResultType.proceed.hashValue)
        var certName = ""
//        if self.isSimulatingCertificateCorruption {
//            certName = corruptedCert
//        } else {
//            certName = cert
//        }

        // Get local and remote cert data
        let remoteCertificateData = SecCertificateCopyData(certificate!) as Data
        let pathToCert            = Bundle.main.path(forResource: certName, ofType: "der")
        let localCertificate      = try! Data(contentsOf: URL(fileURLWithPath: pathToCert!))
        print(" remoteCertificateData: ", remoteCertificateData,"       localCertificate: ", localCertificate, "       serverTrust: ", serverTrust.debugDescription  )

        if ( remoteCertificateData == localCertificate) { //TODO:- this is strictly for tesing puposes, to allow untrusted severs. REMOVE IN PRODUCTION.
            let credential:URLCredential = URLCredential(trust: serverTrust!)
            completionHandler(.useCredential, credential)
        }else if (isServerTrusted && (remoteCertificateData == localCertificate)) {
            let credential:URLCredential = URLCredential(trust: serverTrust!)
            completionHandler(.useCredential, credential)
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }

有人能帮我修复这个tnx吗。

你可以使用AFNETWorking或Almofire库

你可以使用AFNETWorking或Almofire库

你会遇到这个错误,因为你的服务器没有SSL证书,因此它不受信任

“此服务器的证书无效。您可能正在连接假装为“202.73.46.176”的服务器,这可能会使您的机密信息面临风险。”`

仅这部分错误就足以理解发生了什么。一旦您安装了一个受信任的正确有效证书,错误就会消失。您也可以通过在plist中指定它来忽略它

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>yourdomain.com</key>
        <dict>
            <!--Include to allow subdomains-->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!--Include to allow HTTP requests-->
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <!--Include to specify minimum TLS version-->
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
        </dict>
    </dict>
</dict>
NSAppTransportSecurity
NSExceptionDomains
yourdomain.com
n包括多个域
NSTemporary ExceptionalLowsInSecureHttpLoads
NSTemporaryExceptionMinimumTLSVersion
TLSv1.1
但我不会这样做,而只是为您的服务器获取SSL证书


从中引用的.plist密钥会出现该错误,因为您的服务器没有SSL证书,因此不受信任

“此服务器的证书无效。您可能正在连接假装为“202.73.46.176”的服务器,这可能会使您的机密信息面临风险。”`

仅这部分错误就足以理解发生了什么。一旦您安装了一个受信任的正确有效证书,错误就会消失。您也可以通过在plist中指定它来忽略它

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>yourdomain.com</key>
        <dict>
            <!--Include to allow subdomains-->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!--Include to allow HTTP requests-->
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <!--Include to specify minimum TLS version-->
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
        </dict>
    </dict>
</dict>
NSAppTransportSecurity
NSExceptionDomains
yourdomain.com
n包括多个域
NSTemporary ExceptionalLowsInSecureHttpLoads
NSTemporaryExceptionMinimumTLSVersion
TLSv1.1
但我不会这样做,而只是为您的服务器获取SSL证书


从中引用.plist键

我找到了一个更好的答案

创建一个SecurityCertificateManager

import Foundation
import Alamofire


class SecurityCertificateManager {
    static let sharedInstance = SecurityCertificateManager()

    let defaultManager: Alamofire.SessionManager = {
        let serverTrustPolicies: [String: ServerTrustPolicy] = [
            "12.3.3.3": .disableEvaluation
        ]

        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders

        return Alamofire.SessionManager(
            configuration: configuration,
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
        )
    }()
}
这样称呼它

        let service = CommanLinksUtility().getServiceAuthUrl()
        let ticket = UserDefaults.standard.value(forKey: "servicket") as! String
        let baseUrl = "https://12.3.3.3:5051/api/v1/user/find/all/1"
        let header = [ "content-type" : "application/json", "url": service,  "ticket" : ticket ]

      SecurityCertificateManager.sharedInstance.defaultManager.request(baseUrl, method: .get, parameters: header as? [String : AnyObject], encoding: URLEncoding.queryString, headers: header)
            .responseJSON { response in
                let jsonResult = JSON(data: response.data!)
                for anItem in jsonResult["result"].arrayValue {

                }

}

我找到了一个更好的答案

创建一个SecurityCertificateManager

import Foundation
import Alamofire


class SecurityCertificateManager {
    static let sharedInstance = SecurityCertificateManager()

    let defaultManager: Alamofire.SessionManager = {
        let serverTrustPolicies: [String: ServerTrustPolicy] = [
            "12.3.3.3": .disableEvaluation
        ]

        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders

        return Alamofire.SessionManager(
            configuration: configuration,
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
        )
    }()
}
这样称呼它

        let service = CommanLinksUtility().getServiceAuthUrl()
        let ticket = UserDefaults.standard.value(forKey: "servicket") as! String
        let baseUrl = "https://12.3.3.3:5051/api/v1/user/find/all/1"
        let header = [ "content-type" : "application/json", "url": service,  "ticket" : ticket ]

      SecurityCertificateManager.sharedInstance.defaultManager.request(baseUrl, method: .get, parameters: header as? [String : AnyObject], encoding: URLEncoding.queryString, headers: header)
            .responseJSON { response in
                let jsonResult = JSON(data: response.data!)
                for anItem in jsonResult["result"].arrayValue {

                }

}