将iOS应用程序连接到使用Alamofire

时间:2017-06-19 03:02:19

标签: ios ssl alamofire

我正在尝试连接到在localhost上运行的API,因此我可以在iOS模拟器中测试我的应用程序。我正在

  

NSLocalizedDescription =此服务器的证书无效。       您可能正在连接到假装为“127.0.0.1”的服务器       这可能会使您的机密信息面临风险。,       NSErrorFailingURLKey = https://127.0.0.1:8000/post/,       NSErrorFailingURLStringKey = https://127.0.0.1:8000/post/,       NSErrorClientCertificateStateKey = 0

我正在使用 Alamofire This similar question没有帮助。它似乎已经过时的旧版Alamofire了。

我的info.plist已包含

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

如何暂时禁用证书要求,以便我可以在localhost上测试我的应用程序?

这是我更改服务器信任策略后的代码,如其中一个答案

中所述

的ViewController:

class TableViewController: UIViewController {
    let postClient = PostServiceClient.sharedInstance

    override func viewDidLoad() {
        super.viewDidLoad()
        postClient.getPosts()
    }
}

PostServiceClient:

import Alamofire

class PostServiceClient {

    static let sharedInstance: PostServiceClient = PostServiceClient()

    var sessionManager : SessionManager!

    init() {
        let serverTrustPolicies: [String: ServerTrustPolicy] = [
            "https://127.0.0.1:8000/" : .disableEvaluation
        ]

        self.sessionManager =  SessionManager(configuration: URLSessionConfiguration.default,
                                              serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
        )
    }
    static let url = URL.init(string: "https://127.0.0.1:8000/post/")

    // Method to get posts from the wall
    func getPosts(){
        print("Getting posts with completion handler")
        var request = URLRequest(url: PostServiceClient.url!)
        request.httpMethod = "GET"
        self.sessionManager.request(request).responseJSON { (response) in
            guard response.result.isSuccess else {
                print("Error while getting posts: \(String(describing: response.result.error))")
                return
            }
            guard let responseJSON = response.result.value as? [String: Any],
                let results = responseJSON["results"] as? [[String: Any]] else {
                print("Invalid response recieved from service")
                return
            }
            print(responseJSON)
        }

    }
}

以下是我得到的完整输出:

  

获取完成处理程序的帖子2017-06-19 14:22:15.770616-0400   WallAppiOS [28605:9092279] []   nw_coretls_callback_handshake_message_block_invoke_3   tls_handshake_continue:[ - 9812] 2017-06-19 14:22:15.770   WallAppiOS [28605:9092321] NSURLSession / NSURLConnection HTTP加载   失败(kCFStreamErrorDomainSSL,-9813)获取帖子时出错:   可选(错误域= NSURLErrorDomain代码= -1202“证书   此服务器无效。您可能正在连接到的服务器   假装是“127.0.0.1”,可以保密   风险信息。“UserInfo = {NSLocalizedDescription =证书   对于此服务器无效。您可能正在连接到服务器   假装是“127.0.0.1”,可以保密   有风险的信息。,NSLocalizedRecoverySuggestion =你想要吗?   无论如何连接到服务器?,_kCFStreamErrorDomainKey = 3,   NSUnderlyingError = 0x7a3627c0 {错误域= kCFErrorDomainCFNetwork   代码= -1202“(null)”   的UserInfo = {_ kCFStreamPropertySSLClientCertificateState = 0,   _kCFNetworkCFStreamSSLErrorOriginalValue = -9813,_kCFStreamErrorCodeKey = -9813,_kCFStreamErrorDomainKey = 3,kCFStreamPropertySSLPeerTrust =,   kCFStreamPropertySSLPeerCertificates =(       “”)}},_ kCFStreamErrorCodeKey = -9813,NSErrorFailingURLStringKey = https://127.0.0.1:8000/post/,   NSErrorPeerCertificateChainKey =(       “”),NSErrorClientCertificateStateKey = 0,   NSURLErrorFailingURLPeerTrustErrorKey =,   NSErrorFailingURLKey = https://127.0.0.1:8000/post/})

2 个答案:

答案 0 :(得分:1)

在此示例中,我使用serverTrustPolicyManager来处理与未经认证的ssl服务器的连接,我使用单例处理我的应用程序中的所有连接,您必须声明sessionManager,如Alamofire github页面所示

  

确保保留对新SessionManager实例的引用,   否则你的请求将被取消   sessionManager已取消分配。

    class exampleNetworkClient {

        static let sharedInstance: exampleNetworkClient = exampleNetworkClient()

        var sessionManager : SessionManager?

        init() {
            let serverTrustPolicies: [String: ServerTrustPolicy] = [
                "https://127.0.0.1:8000" : .disableEvaluation 
            ]

            self.sessionManager =  SessionManager(configuration: URLSessionConfiguration.default,
                                  serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
            )
        }

        static let portalUrl = URL.init(string:"https://127.0.0.1:8000/exampleserviceUrl")

    func exampleMethod()
    {
        var request = URLRequest(url: iOSETKClient.portalUrl!)
        request.httpMethod = "GET"

        //Important Note that you need to use your custom session manager
        self.sessionManager!.request(request).responseString { (response) in
            ///...RESPONSE LOGIC...///

        }
    }
}

希望这有帮助

答案 1 :(得分:1)

我是通过将ReinerMelian的答案与其他问题中的一个答案结合起来的。

的ViewController:

class TableViewController: UIViewController {

    let postClient = PostServiceClient.sharedInstance

    override func viewDidLoad() {
        super.viewDidLoad()

        postClient.sessionManager.delegate.sessionDidReceiveChallenge = { session, challenge in
            var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
            var credential: URLCredential?

            if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let trust = challenge.protectionSpace.serverTrust {
                disposition = URLSession.AuthChallengeDisposition.useCredential
                credential = URLCredential(trust: trust)
            } else {
                if challenge.previousFailureCount > 0 {
                    disposition = .cancelAuthenticationChallenge
                } else {
                    credential = self.postClient.sessionManager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)

                    if credential != nil {
                        disposition = .useCredential
                    }
                }
            }

            return (disposition, credential)
        }

        postClient.getPosts()
    }
}

服务客户:

class PostServiceClient {

    static let sharedInstance: PostServiceClient = PostServiceClient()

    var sessionManager : SessionManager!

    init() {
        self.sessionManager =  SessionManager(configuration: URLSessionConfiguration.default)
    }
    static let url = URL.init(string: "https://127.0.0.1:8000/post/")

    // Methods to get posts from the wall
    func getPosts(){
        print("Getting posts with completion handler")
        var request = URLRequest(url: PostServiceClient.url!)
        request.httpMethod = "GET"
        self.sessionManager.request(request).responseJSON { (response) in
            guard response.result.isSuccess else {
                print("Error while getting posts: \(String(describing: response.result.error))")
                return
            }
            guard let responseJSON = response.result.value as? [String: Any],
                let results = responseJSON["results"] as? [[String: Any]] else {
                print("Invalid response recieved from service")
                return
            }
            print(responseJSON)
        }

    }
}