Open ChenYilong opened 7 years ago
//TODO: 下一步需要确认一个问题,这里有一个问题需要确认一下,
根据苹果文档说明,按照以下方式可以改变 Cookie
接受策略,文档说明默认策略为NSHTTPCookieAcceptPolicyAlways
,经测试发现默认策略其实为NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
;使用以下方式手动将策略修改为NSHTTPCookieAcceptPolicyAlways
,测试发现 Accept Cookie Always
没有生效,原因需要进一步确定。
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
只会对主域名的Cookie进行缓存,子域名或者请求资源的相关cookie并不会缓存。
因为系统 WebView 的内部的 setCookie 行为有明显 bug,故才在文中给出了一个 cookie 管理器来管理。后序需要更近一步确认下究竟是不是bug,以及如何绕过。
//TODO: 上文提及的主要是 iOS11 下的方案,iOS11之前的兼容方案需要进一步补充,完善。
你好,我现在需要在cookiesDidChangeInCookieStore:时将WKHTTPCookieStore中的内容同步到NSHTTPCookieStorage,但是发现NSHTTPCookieStorage的setCookie:方法同样会触发cookiesDidChangeInCookieStore:,请问有遇到相同的问题吗?我用的是Xcode9 beta5
@jyuuchinen 是的,会出现这种情况。上文的示例代码,也会出现该问题,我仅仅演示了简单的处理,我的目的是将所有的ip换为域名,上面的代码效率虽然低,但也能达到目的。
iOS11 API -[WKHTTPCookieStore deleteCookie:completionHandler:]
在 Xcode Version 9.0 beta 初期的几个版中有bug,不会执行,对应的completionHandler
也不会回调。Xcode Version 9.0 beta 6 已经修复。
WKHTTPCookieStore setcookie 有时候会出现 completionHandler
也不会回调。 这如何处理
WKHTTPCookieStore setcookie 有时候会出现
completionHandler
也不会回调。 这如何处理
你们项目使用WKWebview的场景,会使用IP直连的方案,有没有什么坏处,比如请求的内容还是容易被篡改,没有走域名使用https安全,有尝试过hook DNS解析的方案吗?
iOS 防 DNS 污染方案调研 --- Cookie 业务场景
对应的GitHub仓库镜像地址在这里 ,欢迎提PR进行修改。
概述
本文将讨论下类似这样的问题:
WKWebView 使用 NSURLProtocol 拦截请求无法获取 Cookie 信息
iOS11推出了新的 API
WKHTTPCookieStore
可以用来拦截 WKWebView 的 Cookie 信息用法示例如下:
利用 iOS11 API WKHTTPCookieStore 解决 WKWebView 首次请求不携带 Cookie 的问题
问题说明:由于许多 H5 业务都依赖于 Cookie 作登录态校验,而 WKWebView 上请求不会自动携带 Cookie。比如,如果你在Native层面做了登陆操作,获取了Cookie信息,也使用 NSHTTPCookieStorage 存到了本地,但是使用 WKWebView 打开对应网页时,网页依然处于未登陆状态。如果是登陆也在 WebView 里做的,就不会有这个问题。
iOS11 的 API 可以解决该问题,只要是存在 WKHTTPCookieStore 里的 cookie,WKWebView 每次请求都会携带,存在 NSHTTPCookieStorage 的cookie,并不会每次都携带。于是会发生首次 WKWebView 请求不携带 Cookie 的问题。
解决方法:
在执行
-[WKWebView loadReques:]
前将NSHTTPCookieStorage
中的内容复制到WKHTTPCookieStore
中,以此来达到 WKWebView Cookie 注入的目的。示例代码如下:这个是 iOS11 的API,针对iOS11之前的系统,需要另外处理。
利用 iOS11 之前的 API 解决 WKWebView 首次请求不携带 Cookie 的问题
通过让所有 WKWebView 共享同一个 WKProcessPool 实例,可以实现多个 WKWebView 之间共享 Cookie(session Cookie and persistent Cookie)数据。不过 WKWebView WKProcessPool 实例在 app 杀进程重启后会被重置,导致 WKProcessPool 中的 Cookie、session Cookie 数据丢失,目前也无法实现 WKProcessPool 实例本地化保存。可以采取 cookie 放入 Header 的方法来做。
其中对于
skey=skeyValue
这个cookie值的获取,也可以统一通过domain获取,获取的方法,可以参照下面的工具类:使用方法示例:
发送请求
接收处理请求:
通过
document.cookie
设置 Cookie 解决后续页面(同域)Ajax、iframe 请求的 Cookie 问题;Cookie包含动态 IP 导致登陆失效问题
关于COOKIE失效的问题,假如客户端登录 session 存在 COOKIE,此时这个域名配置了多个IP,使用域名访问会读对应域名的COOKIE,使用IP访问则去读对应IP的COOKIE,假如前后两次使用同一个域名配置的不同IP访问,会导致COOKIE的登录session失效,
如果APP里面的webview页面需要用到系统COOKIE存的登录session,之前APP所有本地网络请求使用域名访问,是可以共用COOKIE的登录session的,但现在本地网络请求使用httpdns后改用IP访问,导致还使用域名访问的webview读不到系统COOKIE存的登录session了(系统COOKIE对应IP了)。IP直连后,服务端返回Cookie包含动态 IP 导致登陆失效。
使用IP访问后,服务端返回的cookie也是IP。导致可能使用对应的域名访问,无法使用本地cookie,或者使用隶属于同一个域名的不同IP去访问,cookie也对不上,导致登陆失效,是吧。
我这边的思路是这样的,
第二种思路将失去DNS调度特性,故不考虑。第一种思路更为可行。
基于 iOS11 API WKHTTPCookieStore 来解决 WKWebView 的 Cookie 管理问题
当每次服务端返回cookie后,在存储前都进行下改造,使用域名替换下IP。 之后虽然每次网络请求都是使用IP访问,但是host我们都手动改为了域名,这样本地存储的 cookie 也就能对得上了。
代码演示:
在网络请求成功后,或者加载网页成功后,主动将本地的 domain 字段为 IP 的 Cookie 替换 IP 为 host 域名地址。
iOS11中也提供了对应的 API 供我们来处理替换 Cookie 的时机,那就是下面的API:
用法如下:
-updateWKHTTPCookieStoreDomainFromIP
方法的实现,在上文已经给出。这个方案需要客户端维护一个IP --> HOST的映射关系,需要能从 IP 反向查找到 HOST,这个维护成本还时挺高的。下面介绍下,更通用的方法,也是iOS11 之前的处理方法:
iOS11 之前的处理方法:NSURLProtocal拦截后,手动管理 Cookie 的存储:
步骤: 做 IP 替换时将原始 URL 保存到 Header 中
然后获取到数据后,手动管理 Cookie:
发送请求前,向请求中添加Cookie信息:
相关的文章: