方案一:检查手机Wifi是否设置了代理

    public func fetchHttpProxy() -> Bool {
        guard let proxy = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() else { return false }
        guard let dict = proxy as? [String: Any] else { return false }
        guard let HTTPProxy = dict["HTTPProxy"] as? String else { return false }
        if(HTTPProxy.count>0){
            return true;
        }
        return false;
    }

1.以场景接口为例,设置了代理检测,手机开启代理,存在代理就直接返回,请求失败。

    func getSelectedFamilyDeviceSomeInfo(parameters : Any?, succeed : @escaping([String : Any]?) -> (), failure : @escaping(Error?) -> ()) {
        let requestUrl:String = SEVER_URL.appending("/developStage/devicegroup/v2/group/someInfo").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
        print(parameters ?? "")
        NSLog("RequestUrl : "+requestUrl)
        
        if self.fetchHttpProxy() {
            print("++++++++++++设置了代理,不让请求=======")
            failure("设置了代理" as? Error)
            return
        }else{
            print("++++++++++++没设置代理,自由请求=======")
        }

        
        // 成功闭包
        let successBlock = { (task: URLSessionDataTask, responseObj: Any?) in
            succeed(responseObj as? [String : Any])
        }
        // 失败的闭包
        let failureBlock = { (task: URLSessionDataTask?, error: Error) in
            failure(error)
        }
        //accesstoken 加入请求头
        getAccessToken(success: {
            self.setHttpHeaderBasicProperty()
            self.post(requestUrl, parameters: parameters, progress: nil, success: successBlock, failure: failureBlock)
        }) {
            failure("Please sign in first" as? Error)
        }
    }

2.注释代理检测,请求正常,界面正常展示,能抓取到场景接口数据

方案二:对证书的验证

1.客户端需要证书(Certification file), .cer格式的文件。(找服务器要,有可能需要转化证书格式)

2、把证书加进项目中,把生成的.cer证书文件直接拖到你项目的相关文件夹中,记得勾选Copy items if neede和Add to targets。

3、参数名意思

AFSecurityPolicy

SSLPinningMode

AFSecurityPolicy是AFNetworking中网络通信安全策略模块。它提供三种SSL Pinning Mode

/**

## SSL Pinning Modes

The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes.

enum {

AFSSLPinningModeNone,

AFSSLPinningModePublicKey,

AFSSLPinningModeCertificate,

}

`AFSSLPinningModeNone`

Do not used pinned certificates to validate servers.

`AFSSLPinningModePublicKey`

Validate host certificates against public keys of pinned certificates.

`AFSSLPinningModeCertificate`

Validate host certificates against pinned certificates.

*/

AFSSLPinningModeNone:完全信任服务器证书;

AFSSLPinningModePublicKey:只比对服务器证书和本地证书的Public Key是否一致,如果一致则信任服务器证书;

AFSSLPinningModeCertificate:比对服务器证书和本地证书的所有内容,完全一致则信任服务器证书;

选择那种模式呢?

AFSSLPinningModeCertificate:最安全的比对模式。但是也比较麻烦,因为证书是打包在APP中,如果服务器证书改变或者到期,旧版本无法使用了,我们就需要用户更新APP来使用最新的证书。

AFSSLPinningModePublicKey:只比对证书的Public Key,只要Public Key没有改变,证书的其他变动都不会影响使用。

如果你不能保证你的用户总是使用你的APP的最新版本,所以我们使用AFSSLPinningModePublicKey。

allowInvalidCertificates

1
2
3
4
/**
 Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
 */
@property (nonatomic, assign) BOOL allowInvalidCertificates;

是否信任非法证书,默认是NO。

validatesDomainName

1
2
3
4
/**
 Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
 */
@property (nonatomic, assign) BOOL validatesDomainName;

是否校验证书中DomainName字段,它可能是IP,域名如*.google.com,默认为YES,严格保证安全性。

4、使用AFSecurityPolicy设置SLL Pinning

1
2
3
4
5
6
7
8
9
10
11
12
13
14
+ (AFHTTPSessionManager *)manager
{
    static AFHTTPSessionManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
     
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        manager =  [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];
 
        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:[AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]]];
        manager.securityPolicy = securityPolicy;
    });
    return manager;
}

最新文章

  1. 断言与异常(Assertion Vs Exception)
  2. ServletConfig 可以做啥
  3. R中list对象属性以及具有list性质的对象
  4. python day1 常用模块
  5. Libvirt 网络管理
  6. 查表法计算CRC16校验值
  7. JavaWeb_Day10_学习笔记1_response(3、4、5、6、7、8、9)发送状态码、响应、重定向、定时刷新、禁用浏览器缓存、响应字节数据、快捷重定向方法、完成防盗链
  8. Delphi PChar与String互转
  9. JDBC之ResultSet
  10. QML基础(六篇文章)
  11. ClusterWare 服务介绍
  12. 分享一个 jmeter ant的build.xml
  13. JAVA NIO 主要概念
  14. JAVA-大白话探索JVM-运行时内存(三)
  15. MySQL数据类型及使用场景
  16. "Regressing Robust and Discriminative 3D Morphable Models with a very Deep Neural Network" 解读
  17. wavepicking
  18. org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session异常解决办法
  19. asp.net利用QQ邮箱发送邮件,关键在于开启pop并设置授权码为发送密码
  20. mysql中事务

热门文章

  1. 1_ios系统httpstatus状态为0
  2. 【Java】线程池梳理
  3. 用云服务器搭建frp服务(超详细)
  4. 动力节点——day08
  5. OSI七层协议补充与socket套节字
  6. HashSet集合存储数据的结构(哈希表)-Set集合存储元素不重复的原理
  7. Time Series Analysis (Best MSE Predictor & Best Linear Predictor)
  8. MySQL-SQL语句查询关键字
  9. Vue36 hash模式和history模式
  10. linux08-进程管理