WKWebView的cookie注入问题

前因

WKWebView有自己的进程,独立于iOS App的进程,使用自己的存储空间来存储cookie和cache,WKWebView会忽视NSURLCache、NSHTTPCookieStorage、NSCredentialStorage这些默认的网络存储。 WKWebView 发起的请求不会自动带上存储于 NSHTTPCookieStorage 容器中的 Cookie。

所以我们需要自己注入cookie到WKWebView中

iOS 11以后

苹果提供了WKHTTPCookieStore处理WKWebView的cookie,我们将NSHTTPCookieStorage里面的cookie取出后设置到WKHTTPCookieStore中就可以了,代码示例

1
2
3
4
NSArray *cookieArr = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
[cookieArr enumerateObjectsUsingBlock:^(NSHTTPCookie * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self.webView.configuration.websiteDataStore.httpCookieStore setCookie:obj completionHandler:nil];
}];

iOS 11以前

WKWebView中cookie的解决方案有:

方案1:WKWebView loadRequest 前,在 request header 中设置 Cookie, 解决首个请求 Cookie 带不上的问题;

缺陷:只能解决指定的一个URL的请求,涉及到同域的Ajax跳转还是会缺失cookie

方案2: 通过 document.cookie 设置 Cookie 解决后续页面(同域)Ajax、iframe 请求的 Cookie 问题;

缺陷:不能解决跨域cookie的问题

方案3:每次页面跳转的时候回调用decidePolicyForNavigationAction回调,那么就可以在回调里拦截请求,加入cookie后重新发送。

缺陷:loadRequest是加载mainFrame请求,所以依然解决不了页面 iframe 跨域请求的 Cookie 问题

由于暂时没有遇到跨域请求cookie的问题,所以这里就不讨论方案3了。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
NSArray *cookieArr = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
NSMutableString *str = [NSMutableString new];
for (NSHTTPCookie *ck in cookieArr) {
if ([ck.domain containsString:@".taobao.com"]) {
[str appendFormat:@"document.cookie = '%@=%@;domain=.taobao.com;path=/';\n", ck.name, ck.value];
}
}
// 方案1
request.allHTTPHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArr];
// 方案2
WKUserScript *script = [[WKUserScript alloc] initWithSource:str injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[self.webView.configuration.userContentController addUserScript:script];

方案2中,需要注意多cookie注入时,注入的字符串是以下格式,有多个 document.cookie 标志,而不是只有一个

1
2
3
4
5
document.cookie = 'RCRM_CODCS_WELOG_ID=B2VTGSYJHKKKECM8ITC0F95JFD70OD19420211012105246833;domain=.taobao.com;path=/';
document.cookie = 'symmetricKey=false;domain=.taobao.com;path=/';
document.cookie = 'taobaoToken=0AB9696085D923A8345E009504580D0B8694890CC2029A4D52EB5F63FB4F8AC9B61654474;domain=.taobao.com;path=/';
document.cookie = 'userId=ozf_BuHlDefVjJwSuEQ5xxGL7ZvI;domain=.taobao.com;path=/';
document.cookie = 'userIdType=2;domain=.taobao.com;path=/';

调试

通过iPhone连接Mac电脑,使用Safari的开发工具可以调试手机的H5页面,可以验证cookie是否注入成功。如下图,cookie成功注入

参考


WKWebView的cookie注入问题
http://example.com/2021/10/12/WKWebView的cookie注入问题/
作者
guanzhendong
发布于
2021年10月12日
许可协议