原文地址 https://lm1024.xyz/archives/34
看了這篇有關(guān)對(duì) iOS app 進(jìn)行安全加固看到防止http抓包后感覺自己能做一下實(shí)驗(yàn)。
分析
1畦浓、項(xiàng)目中能用到網(wǎng)絡(luò)請(qǐng)求的地方一般都為調(diào)API接口普泡、上傳文件齿坷、加載文件厦坛、拉取圖片幾種情況桦锄。
2译暂、第三方依賴庫(kù)基礎(chǔ) AFNetwork SDWebImage抠忘。
3、第三方庫(kù)源碼分析外永。
- AFNetworking
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
self = [super init];
if (!self) {
return nil;
}
if (!configuration) {
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
}
self.sessionConfiguration = configuration;
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.maxConcurrentOperationCount = 1;
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
self.responseSerializer = [AFJSONResponseSerializer serializer];
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
#if !TARGET_OS_WATCH
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
self.lock = [[NSLock alloc] init];
self.lock.name = AFURLSessionManagerLockName;
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
for (NSURLSessionDataTask *task in dataTasks) {
[self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
}
for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
[self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
}
for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
[self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
}
}];
return self;
}
從這段代碼中我們可以看出AFNetworking
所有的session
的產(chǎn)生都是self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
這行代碼負(fù)責(zé)產(chǎn)生
- SDWebImage
SDWebImage負(fù)責(zé)將網(wǎng)絡(luò)圖片下載到本地并緩存的功能崎脉,那么我們只需要分析下載器相關(guān)的部分代碼,從SDWebImageDownloader
- (void)createNewSessionWithConfiguration:(NSURLSessionConfiguration *)sessionConfiguration {
[self cancelAllDownloads];
if (self.session) {
[self.session invalidateAndCancel];
}
sessionConfiguration.timeoutIntervalForRequest = self.downloadTimeout;
/**
* Create the session for this task
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
* method calls and completion handler calls.
*/
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
delegate:self
delegateQueue:nil];
}
從這段代碼中能看出session
也是由self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
這行代碼產(chǎn)生。
解決方案
(1)只針對(duì)AFNetwork
我們可以有
1象迎、繼承AFHTTPSessionManager
在子類中重寫- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration
方法
2荧嵌、hook - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration
方法
3、hook + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
系統(tǒng)方法
(2)只針對(duì)SDWebImageView
我們有
1砾淌、SDWebImageDownloader
是一個(gè)單例啦撮,那么我們可以 直接設(shè)置[SDWebImageDownloader sharedDownloader].sessionConfiguration.connectionProxyDictionary = @{}
2、hook - (void)createNewSessionWithConfiguration:(NSURLSessionConfiguration *)sessionConfiguration
3汪厨、hook + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
系統(tǒng)方法
基于上面的情況和項(xiàng)目整體考慮采用了 + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
系統(tǒng)方法
源碼
#import "NSURLSession+PLCategory.h"
#import <objc/runtime.h>
void swizzing(Class class, SEL originalSelector, SEL swizzledSelector)
{
Method originalMethod = class_getClassMethod(class, originalSelector);
Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
@implementation NSURLSession (QYCategory)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [NSURLSession class];
swizzing(class, @selector(sessionWithConfiguration:), @selector(qy_sessionWithConfiguration:));
swizzing(class, @selector(sessionWithConfiguration:delegate:delegateQueue:),
@selector(qy_sessionWithConfiguration:delegate:delegateQueue:));
});
}
+ (NSURLSession *)qy_sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
delegate:(nullable id<NSURLSessionDelegate>)delegate
delegateQueue:(nullable NSOperationQueue *)queue
{
if (!configuration)
{
configuration = [[NSURLSessionConfiguration alloc] init];
}
configuration.connectionProxyDictionary = @{};
return [self qy_sessionWithConfiguration:configuration delegate:delegate delegateQueue:queue];
}
+ (NSURLSession *)qy_sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
{
if (configuration)
{
configuration.connectionProxyDictionary = @{};
}
return [self qy_sessionWithConfiguration:configuration];
}
@end