wkwebview做IP直连且需要302跳转携带Cookie时遇到的坑

1,正常逻辑
客户端通过域名携带accessToken用wkwebview加载,发送一个接口请求给服务端,服务端通过accessToken获取到对应的SessionID,将SID种到对应H5域名对应的Cookie下。返回给客户端一个302的重定向,客户端收到302重定向自动加载H5页面,这时H5页面会通过gettoken接口把SID的Cookie自动带到请求中,服务器验证SID,能找到对应的Session则自动登录成功。
2,IP直连情况下的逻辑与遇到的坑
这期间主要要解决两个坑
(1)Set-Cookie无法被成功种到客户端的CookieStorage里边
我们IP请求时会在Host中把域名带上,对于服务器来说是无感知的,也就是说服务器收到的都是域名的请求,只不过我们这里把dns解析给省略掉了。所以服务端只能在302后的域名下种Cookie,但是由于我们客户端是IP请求的,所以Cookie跨域了。跨域的结果是服务端返回的Set-Cookie无法被成功种到客户端的CookieStorage里边。
(2)如果自己手动将Set-Cookie的内容保存,需要同步给JS,而不是在302后网页的请求中把Cookie带到Header里。
因为H5是调用gettoken的时候使用的SID,而不是网页,所以同步给JS后,JS发起请求才会自动带上cookie。
3,具体实践
(1)发现问题当天把请求换成IP直连,Host带域名后,通过charles抓包,发现服务端返回了Set-Cookie,但是通过下面两种方式获取cookie均获取不到,那天晚上一头雾水,不知道哪里出了问题。
[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies

[self.webView.configuration.websiteDataStore.httpCookieStore getAllCookies:^(NSArray * _Nonnull cookies) {
NSLog(@"%@",cookies);
}]
(2)后来想是不是后端把IP也给种上就好了?然后发现后端把IP种上后客户端确实能正常获取登录状态了。
(3)但是因为我们有多条线路,一个域名可能会对应多个IP,一个IP可能会对应多个域名。服务端怎么知道我们直接IP请求的时候是哪个IP?(因为对服务端来说都是获取到的域名,无感知的)然后我们想在Header里带一个字段过去,表示请求的IP,服务端是不是就能在IP下种上Cookie了?实验发现确实可行。
(4)但问题来了,按说客户端使用IP直连对服务端是无感知的,客户端只是省了dns解析这一步,那这个兼容确需要服务端来做?如果302跳转前后不是一个域的话Cookie是不是也种不上了?毕竟Set-Cookie可能只对当前域种Cookie可行。
(5)然后又想了想,是不是可以在服务端返回的302 responseHeader里手动把Set-Cookie给获取到,然后想给哪个域种Cookie由客户端自己定?
实验发现,wkwebview无法获取到302的responseHeader,只能获取到最终请求的responseHeader。
然后在网上发现了https://github.com/luowenxing/PWKWebView
原理是把需要在wkwebview中发起的请求改成用NSURLSession去发起,这时就能监听到302的responseHeader了,然后从header中把Set-Cookie内容设置到NSHTTPCookieStorage中去,然后调用JS代码把Cookie同步给JS。
(6)由于PWKWebView是swift的,我们项目全部OC,所以花了点时间把它翻译成OC,运行后成功把Cookie获取到,然后再302跳转之后的requestHeader中把Cookie给加上去了。但是问题又来了,为什么还是登录不上去呢?
(7)去咨询H5说是在网页的request里加上cookie是给服务器的,他们是获取不到的,他们是从JSCookieStorage里自动取cookie的,然后结合charles抓包发现,gettoken接口是没有带cookie的,H5最关键的是这个接口要带上cookie才行。然后查看自己代码同步给JS那一块,发现少了一个单引号,修复问题后再次运行,果然可以正常登录了。charles上gettoken接口成功携带上了cookie。

你可能感兴趣的:(wkwebview做IP直连且需要302跳转携带Cookie时遇到的坑)