1

我的 ios 应用程序中的 ssl 证书固定有问题,我想要的是使用 alamofire 向所有请求添加 ssl 固定证书,所以下面是我的 alamofire 管理器代码,当我运行应用程序时,我总是收到此错误:

加载失败,错误域=NSURLErrorDomain 代码=-999 “取消” UserInfo={NSErrorFailingURLStringKey= https://myWebsite.com/token , NSErrorFailingURLKey= https://myWebsite.com/token , _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask .<1 >" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<1>, NSLocalizedDescription=cancelled} [-999]

class AFManager : NSObject{

private var sessionManager: SessionManager?


required override init() {
    super.init()

    enableCertificatePinning()

}

private func enableCertificatePinning() {
    let certificates = getCertificates()
    let trustPolicy = ServerTrustPolicy.pinCertificates(
        certificates: certificates,
        validateCertificateChain: true,
        validateHost: true)
    let trustPolicies = [ "myWebsite.com": trustPolicy ]
    let policyManager =  ServerTrustPolicyManager(policies: trustPolicies)
    sessionManager = SessionManager(
        configuration: .default,
        serverTrustPolicyManager: policyManager)
}

private func getCertificates() -> [SecCertificate] {
    let url = Bundle.main.url(forResource: "myWebsitessl", withExtension: "cer")!
    let localCertificate = try! Data(contentsOf: url) as CFData
    guard let certificate = SecCertificateCreateWithData(nil, localCertificate)
        else { return [] }

    return [certificate]
}



///without headers (post)
//used this to registration
class func requestPOSTURL(_ strURL : String, params : [String : AnyObject]?, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void){
    URLCache.shared.removeAllCachedResponses()
    self.init().sessionManager?.request(strURL, method: .post, parameters: params, encoding: URLEncoding.httpBody).responseJSON { (responseObject) -> Void in

        //print(responseObject)

        if responseObject.result.isSuccess {
            let resJson = JSON(responseObject.result.value!)
            success(resJson)
        }
        if responseObject.result.isFailure {
            let error : Error = responseObject.result.error!
            failure(error)
        }
    }
}


///// response string (post)
//used this in login // used in change password
class func strRequestPOSTURL(_ strURL : String, params : [String : String]?, headers : [String : String]?, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void){
    URLCache.shared.removeAllCachedResponses()
    self.init().sessionManager?.request(strURL, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: headers).responseJSON { (response) in
        //print(response)

        if response.result.isSuccess {
            let resJson = JSON(response.result.value!)
            success(resJson)
        }
        if response.result.isFailure {
            let error : Error = response.result.error!

            failure(error)
        }

    }

  }

}

我的代码是这样的,见下面的代码,它正在工作,但我想要证书固定以确保安全,所以我在上面的代码中添加了东西(如 sessionManager、init()、enableCertificatePinning() 和 getCertificates()),然后它不工作

class AFManager : NSObject{


///without headers (post)
//used this to registration
class func requestPOSTURL(_ strURL : String, params : [String : AnyObject]?, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void){
    URLCache.shared.removeAllCachedResponses()
    Alamofire.request(strURL, method: .post, parameters: params, encoding: URLEncoding.httpBody).responseJSON { (responseObject) -> Void in

        //print(responseObject)

        if responseObject.result.isSuccess {
            let resJson = JSON(responseObject.result.value!)
            success(resJson)
        }
        if responseObject.result.isFailure {
            let error : Error = responseObject.result.error!
            failure(error)
        }
    }
}


///// response string (post)
//used this in login // used in change password
class func strRequestPOSTURL(_ strURL : String, params : [String : String]?, headers : [String : String]?, success:@escaping (JSON) -> Void, failure:@escaping (Error) -> Void){
    URLCache.shared.removeAllCachedResponses()
    Alamofire.request(strURL, method: .post, parameters: params, encoding: URLEncoding.httpBody, headers: headers).responseJSON { (response) in
        //print(response)

        if response.result.isSuccess {
            let resJson = JSON(response.result.value!)
            success(resJson)
        }
        if response.result.isFailure {
            let error : Error = response.result.error!

            failure(error)
        }

    }

  }

}

我通过将证书拖放到项目中将其添加到我的项目中,请帮助,我觉得我的代码有一些错误提前谢谢

4

2 回答 2

1

错误-999最常见于您在使用时SessionManagerdeinit取消,导致您的所有请求都被取消。从您的代码看来,您根本没有使用sessionManager您通过自定义创建的变量ServerTrustPolicy,即使您AFManager创建的任何实例都可能超出范围,导致deinit.

于 2019-02-25T05:36:33.190 回答
0

你可以使用sessionManager,我在下面使用这个类,它从你的包中创建证书数组;

class NetworkManager
{
    static let sharedInstance = NetworkManager()
    var manager: SessionManager?

    init()
    {
        var certificates = ServerTrustPolicy.certificates(in: Bundle.main)

        let serverTrustPolicies: [String: ServerTrustPolicy] = [
            "yourUrl.com": .pinCertificates(
                certificates: ServerTrustPolicy.certificates(in: Bundle.main),
                validateCertificateChain: true,
                validateHost: true
            )
        ]

        manager = SessionManager(
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
        )


    }
}

然后我确实要求这样,

     //request depends on your needs. Post, get etc..
        var request = URLRequest(url: yourUrl)
        request.httpMethod = HTTPMethod.get.rawValue
        request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")

        networkManager.manager!.request(request).responseJSON

顺便说一句,不要忘记创建你的 networkManager 对象

var networkManager = NetworkManager.sharedInstance
于 2020-02-26T13:10:42.650 回答