我们都知道Cookie Policy会影响服务器能否在客户端(iOS设备中)种cookie
iOS系统中通过NSHTTPCookieStorage
类的单例来管理Cookie Policy, 并且有以下几中Cookie Policy:
- NSHTTPCookieAcceptPolicyAlways --- Accept all cookies.
- NSHTTPCookieAcceptPolicyNever --- Reject all cookies.
- NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain --- Accept cookies only from the main document domain.
虽然Apple官方文档中表示NSHTTPCookieAcceptPolicyAlways(This is the default cookie accept policy.)
是默认的配置, 但是我们实际在一个全新的BunldeID的App中,打印看到的初始配置是NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
, 代码结构如下:
-(NSString *)plicyNameBy:(NSHTTPCookieAcceptPolicy)plicy{
NSString *ret = nil;
switch (plicy) {
case NSHTTPCookieAcceptPolicyAlways:
return @"NSHTTPCookieAcceptPolicyAlways";
break;
case NSHTTPCookieAcceptPolicyNever:
return @"NSHTTPCookieAcceptPolicyNever";
break;
case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
return @"NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain";
break;
}
return ret;
}
-(void)printPolicy{
NSHTTPCookieAcceptPolicy policy = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookieAcceptPolicy;
NSLog(@"当前cookie storage 策略: %@",[self plicyNameBy:policy]);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self printPolicy]; // 打印结果是 NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
return YES;
}
1. Cookie Policy的正常情况
在测试之前, 首先需要将APP从iPhone上删除以后, 运行如下代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self printPolicy];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
[self printPolicy];
return YES;
}
输出结果如下
2018-11-14 16:12:25.194597+0800 CookiePolicyDemo[72266:4789124] 当前cookie storage 策略: NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
2018-11-14 16:12:25.195228+0800 CookiePolicyDemo[72266:4789124] DiskCookieStorage changing policy from 2 to 1, cookie file: file:///private/var/mobile/Containers/Data/Application/142771D7-0798-45F6-86B3-5EEF3921672C/Library/Cookies/Cookies.binarycookies
2018-11-14 16:12:25.195274+0800 CookiePolicyDemo[72266:4789124] 当前cookie storage 策略: NSHTTPCookieAcceptPolicyNever
此时, 不要删除APP, 将设置Policy那句语句注释掉,直接重新编译Run起APP, 代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self printPolicy];
// [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
[self printPolicy];
return YES;
}
结果如下:
2018-11-14 16:15:53.618973+0800 CookiePolicyDemo[72283:4789890] 当前cookie storage 策略: NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
2018-11-14 16:15:53.619013+0800 CookiePolicyDemo[72283:4789890] 当前cookie storage 策略: NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
我们可以看出, Cookie Policy 恢复成NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
. 这种情况是我们认可的正常情况.
2. Cookie Policy的异常情况!!!
- 将手机上的APP删掉!!!!!!!
- 将Cookie Storage策略设置成
Never
, 然后Run:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self printPolicy];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
[self printPolicy];
return YES;
}
// 此时结果会正常打印, 和上一节内容一样
- 当APP进入手机界面以后, 快速点击Home,让APP进入后台. (或者在手机上双击home, 直接关闭APP)
- 在Xcode中将
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
语句注释掉:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self printPolicy];
// [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
[self printPolicy];
return YES;
}
- 此时上一次配置
Never
的APP还在设备上运行, 在注释上面代码以后, 直接按Xcode的Run. APP会再次启动,打印的Cookie Policy居然是:
2018-11-14 16:30:25.452648+0800 CookiePolicyDemo[72375:4794345] 当前cookie storage 策略: NSHTTPCookieAcceptPolicyNever
2018-11-14 16:30:25.452683+0800 CookiePolicyDemo[72375:4794345] 当前cookie storage 策略: NSHTTPCookieAcceptPolicyNever
- 此时, 只要我们没有主动将APP没有删除, 同时在新的代码中没有主动调用
[NSHTTPCookieStorage +setCookieAcceptPolicy:]
方法去设置Cookie Policy, 那么此APP就永远不能被后台种植Cookie了!!!!!因为此时, 我们的Cookie Policy 永远是NSHTTPCookieAcceptPolicyNever
!!!!!
按常理, 我们在注释掉[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever]
以后, 系统的 Cookie Policy 会修改成默认的NSHTTPCookieAcceptPolicyAlways
或者NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
, 但是这里的结果缺与我们直观感受有所出入!!!
总结
这个问题让我们认识到, iOS系统中的Cookie Storage Policy
可能用的一个外部文件存储相关配置, 只要我们手动调用过[NSHTTPCookieStorage +setCookieAcceptPolicy:]
方法, 那么该配置就会被写入该外部文件.
也就是说, 只要以下3个条件同时满足, 原app相关的外部配置依然会生效!!!:
- 我们调用过
+setCookieAcceptPolicy
, 并且将该APP安装到的iOS设备 - 在该APP运行情况时, 有异常情况发生(APP进入后台,APP被手动终止)
- 将调用过
+setCookieAcceptPolicy
注释以后的APP, 重新安装在该设备上, 重用原APP的资源.
解决该问题只能, 通过代码将Cookie Storage
设置成NSHTTPCookieAcceptPolicyAlways
或者NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
.
在SDK开发过程中, 要防止壳APP对 Cookie Sotrage
的配置影响SDK内部的Cookie相关内容, 还是建议手动存储后台在 Response 中的Set-Cookie
中的Cookie, 而不要使用系统层的Cookie存储逻辑.
ps: 以上内容中, 我只使用Xcode - Run 来表示重装APP, 实际情况中可能, 用户在进入我们APP以后, 进入app store更新我们的app,会导致原打开的app进入后台!!!!! 满足上面提到的3个条件
参考
- 关于ios的Cookie那些事
- iOS htttp网络请求cookie的读取与写入(NSHTTPCookieStorage)
- NSMutableURLRequest 设置cookie 及 NSHTTPCookieStorage机制
- iOS开发WKWebView Cookie的读取与写入,与UIWebView的Cookie共享
- What is the default cookieAcceptPolicy
- Apple Doc
- Understanding iOS Cookie Accept Policy
- React Native持久化sessions #9
- Does NSURLConnection automatically persist cookies sent from server?
网友评论