Как подключить localhost (с недопустимым сертификатом) с помощью Alamofire?

Этот мой первый проект использует быстрый. Я использую alamofire для подключения API. У меня есть локальная копия API, которую я хочу использовать для отладки, поэтому я могу установить тестовые данные, потому что у удаленного API уже есть реальные данные, с которыми я не могу общаться.

Проблема в том, что я получаю следующую ошибку при попытке получить доступ к https://localhost:8443/MyProject

Необязательный (Error Domain = NSURLErrorDomain Code = -1202). Сертификат для этого сервера недействителен. Возможно, вы подключаетесь к серверу, который притворяется "localhost", который может угрожать вашей конфиденциальной информации ". UserInfo = 0x7fbeb8c61ff0 {NSURLErrorFailingURLPeerTrustErrorKey =, NSLocalizedRecoverySuggestion = Хотелось бы подключиться к серверу в любом случае?, _kCFStreamErrorCodeKey = -9813, NSUnderlyingError = 0x7fbeb8ea5c00" Операция не может быть выполнена. (KCFErrorDomainCFNetwork error -1202.) ", NSLocalizedDescription = Сертификат для этого сервера недействителен Возможно, вы подключаетесь к серверу, который притворяется" локальным ", что может угрожать вашей конфиденциальной информации. NSErrorFailingURLKey = https://localhost: 8443/myproject/api/loginUser.pdo, NSErrorFailingURLStringKey = https://localhost: 8443/myproject/api/loginUser.pdo, _kCFStream ErrorDomainKey = 3})

Я нашел много решений для большинства из них для Objective-c, используя setAllowsAnyHTTPSCertificate или используя делегат для подключения. но я не смог найти равный метод для setAllowsAnyHTTPSCertificate в swift, и я не уверен, как установить делегат для соединения при использовании alamofire. любые идеи, что мне нужно делать?

  • Я знаю, что setAllowsAnyHTTPSCertificate является приватным api и приведет к тому, что проект будет отклонен Apple. Я хочу использовать его только при отладке, после чего он будет удален до публикации проекта.

Спасибо заранее.

Ответы

Ответ 1

Вы можете легко переопределить поведение задачи по умолчанию в Alamofire, используя закрытие переопределения SessionDelegate. Вот пример того, как вы можете разрешить Alamofire принимать недействительные сертификаты:

ВАЖНО: Пожалуйста, не используйте это в любом производственном коде. Безопасность ОЧЕНЬ важна, и эта реализация полностью игнорирует механизмы безопасности в Alamofire. Используйте на свой страх и риск!

let manager = Alamofire.Manager.sharedInstance

manager.delegate.sessionDidReceiveChallenge = { session, challenge in
    var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
    var credential: NSURLCredential?

    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
        disposition = NSURLSessionAuthChallengeDisposition.UseCredential
        credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
    } else {
        if challenge.previousFailureCount > 0 {
            disposition = .CancelAuthenticationChallenge
        } else {
            credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)

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

    return (disposition, credential)
}

Мы (Alamofire TC) намерены внедрить пиннинг TLS и несколько других функций, связанных с безопасностью в Alamofire 1.3.0.


UPDATE

Выход Alamofire 1.3.0 отсутствует и добавляет МНОГОУлучшую поддержку для настройки запросов проверки подлинности доверия сервера. Для получения дополнительной информации ознакомьтесь с разделом Security README.

Ответ 2

Swift 3 версия кода @cnoon

    manager.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.manager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)

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

        return (disposition, credential)
    }

Ответ 3

Swift 3

В моем случае, когда я использую клиентскую библиотеку swagger, я изменил свой код, чтобы протестировать локальный сервер следующим образом:

 open func createSessionManager() -> Alamofire.SessionManager {
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = buildHeaders()

    let serverTrustPolicies: [String: ServerTrustPolicy] = ["localhost": .disableEvaluation]

    return Alamofire.SessionManager(configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
}

Ответ 4

Замена https на http моего базового url. разрешили ошибку.