example ios swift https alamofire

ios - example - download alamofire swift 3



Alamofire con un certificado autofirmado/ServerTrustPolicy (4)

Quiero usar Alamofire para comunicarme con mi servidor a través de una conexión https con un certificado autofirmado. Mi entorno se ejecuta en localhost. He intentado conectarme, pero la respuesta todo el tiempo es así:

Success: false Response String: nil

Lo he hecho con el siguiente código:

import Foundation import UIKit import Alamofire class MessageView: UITableViewController { let defaultManager: Alamofire.Manager = { let serverTrustPolicies: [String: ServerTrustPolicy] = [ "localhost": .DisableEvaluation ] let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders return Alamofire.Manager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) }() override func viewDidLoad() { super.viewDidLoad() defaultManager .request(.GET, "https://localhost:3443/message") .responseJSON { _, _, result in print("Success: /(result.isSuccess)") print("Response String: /(result.value)") } } }

He creado los certificados del lado del servidor con esta línea de bash:

openssl req -x509 -nodes -days 999 -newkey rsa:2048 -keyout server.key -out server.crt

No sé qué estoy haciendo mal. La ayuda sería genial.

### Actualizar ###

Aquí está la solicitud cURL. En mi opinión, no hay problema, ¿o me equivoco?

curl -X GET https://localhost:3443/message -k -v * Trying ::1... * Connected to localhost (::1) port 3443 (#0) * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 * Server certificate: teawithfruit > GET /message HTTP/1.1 > Host: localhost:3443 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: application/json; charset=utf-8 < Content-Length: 1073 < Date: Tue, 15 Sep 2015 06:20:45 GMT < Connection: keep-alive < * Connection #0 to host localhost left intact [{"_id":"55f3ed2d81a334558241e2f4","email":"[email protected]","password":"abc","name":"teawithfruit","language":"en","__v":0,"timestamp":1442049325159,"messages":[{"_id":"55f40553e568236589772c61","user":"55f3ed2d81a334558241e2f4","language":"en","message":"hello world","__v":0,"timestamp":1442055507301,"id":"55f40553e568236589772c61"},{"_id":"55f48b2b02e7b059b54e99f6","user":"55f3ed2d81a334558241e2f4","language":"en","message":"hello world","__v":0,"timestamp":1442089771312,"id":"55f48b2b02e7b059b54e99f6"}],"id":"55f3ed2d81a334558241e2f4"}]

### Actualización 2 ###

Disculpa por la respuesta tardía. Aquí están los dos debugPrints:

Solicitar debugPrint:

$ curl -i / -H "Accept-Language: en-US;q=1.0" / -H "Accept-Encoding: gzip;q=1.0,compress;q=0.5" / -H "User-Agent: Message/com.teawithfruit.Message (1; OS Version 9.0 (Build 13A340))" / "https://localhost:3443/message"

Resultado debugPrint:

FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://localhost:3443/message, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://localhost:3443/message}

### Actualización 3 ###

Aquí está el error completo con tal vez un problema de ATS?

nil $ curl -i / -H "Accept-Language: en-US;q=1.0" / -H "Accept-Encoding: gzip;q=1.0,compress;q=0.5" / -H "User-Agent: Message/com.teawithfruit.Message (1; OS Version 9.0 (Build 13A340))" / "https://localhost:3443/message" 2015-10-17 15:10:48.346 Message[25531:1001269] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) FAILURE: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fdc3044b740>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=<CFArray 0x7fdc2a7ca300 [0x10f7037b0]>{type = immutable, count = 1, values = ( 0 : <cert(0x7fdc31d31670) s: teawithfruit i: teawithfruit> )}, NSUnderlyingError=0x7fdc30064bd0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7fdc3044b740>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7fdc2a7ca300 [0x10f7037b0]>{type = immutable, count = 1, values = ( 0 : <cert(0x7fdc31d31670) s: teawithfruit i: teawithfruit> )}}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://localhost:3443/message, NSErrorFailingURLStringKey=https://localhost:3443/message, NSErrorClientCertificateStateKey=0} Success: false Response String: nil


Así que sé que ha pasado un tiempo, pero tuve exactamente el mismo problema. Y encontré una solución con las respuestas anteriores. Tuve que agregar 2 cosas a trustPolicies:

let defaultManager: Alamofire.Manager = { let serverTrustPolicies: [String: ServerTrustPolicy] = [ // Here host with port (trustPolicy is my var where I pin my certificates) "localhost:3443": trustPolicy //Here without port "localhost": .disableEvaluation ] let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders return Alamofire.Manager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) }()

También en Info.plist había que añadir:

<key>AppTransportSecurity</key> <dict> <key>AllowsArbitraryLoads</key> <true/> </dict>


Debe agregar el dominio de port cuando cree su diccionario ServerTrustPolicy .

let defaultManager: Alamofire.Manager = { let serverTrustPolicies: [String: ServerTrustPolicy] = [ "localhost:3443": .DisableEvaluation ] let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders return Alamofire.Manager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) }()


Mi enfoque para https autofirmados. El ServerTrustPolicyManager es una clase open , y su función serverTrustPolicy está open . Por lo que puede ser anulado.

En mi caso, la lista de servidores crecerá en el futuro. Si codifico la lista https, tendré que mantener la lista al agregar un nuevo servidor https. Por lo tanto, decido anular la clase ServerTrustPolicyManager para satisfacer mis necesidades.

// For Swift 3 and Alamofire 4.0 open class MyServerTrustPolicyManager: ServerTrustPolicyManager { // Override this function in order to trust any self-signed https open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? { return ServerTrustPolicy.disableEvaluation } }

Entonces,

let trustPolicies = MyServerTrustPolicyManager(policies: [:]) let manager = Alamofire.SessionManager(configuration: sessionConfig, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)


Para Swift 4:

private static var Manager : Alamofire.SessionManager = { // Create the server trust policies let serverTrustPolicies: [String: ServerTrustPolicy] = [ "your domain goes here": .disableEvaluation ] // Create custom manager let configuration = URLSessionConfiguration.default configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders let man = Alamofire.SessionManager( configuration: URLSessionConfiguration.default, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) return man }()

Entonces lo llamas así:

Manager.upload(body.data(using: .utf8)!, to: url, method: .post, headers: headers)

Créditos a Cnoon