android webview同步cookie

在进行APP+H5混合开发的时候,一些功能是用native方法实现的,如登陆,一些功能是用H5实现的。所以往往需要将在native方法登陆的状态同步到H5中避免再次登陆。这种情况在Android开发中比较常见,因为Android不会自动同步cookie到WebView。做iOS开发则不用担心这个问题,因为iOS内部已经实现了cookie同步。本文将会介绍两种cookie同步的方式,并重点分析WebView的cookie机制。在开始之前先讲一下基于session的登录验证。

基于session的登录验证:
基于session的登录验证,会在程序请求接口的时候判断服务器端是否有当前会话的session,如果没有则被认为没有登录。客户端没有session这一概念,但有cookie与其对应。每一个session都有一个session id作为唯一标识。在登录成功后服务器会在请求头中返回cookie,cookie包含着这次登录会话的session id,在接下来的请求中只需要将登陆返回的cookie设置到请求头中便可以通过验证。

访问服务器流程:
1)第一次访问服务器的时候,会在响应头里面看到Set-Cookie信息(只有在首次访问服务器的时候才会在响应头中出现该信息)

image.png

上面的图JSESSIONID=ghco9xdnaco31gmafukxchph;Path=/acr,

浏览器会根据响应头的set-cookie信息设置浏览器的cookie并保存之,注意此cookie由于没有设置cookie有效日期,所以在关闭浏览器的情况下会丢失掉这个cookie。

每次webview打开的url后,后台的jsessionid都是不同的(最开始是没有的),无法区分同一个用户。【请求cookie中的jsessionid是变化的】,所以访问需要登录信息(jsessionid)的页面时必须同步cookie。如果遇到ajax没有同步成功的情况,可以考虑url传参。对于第一次请求重要接口没有jsessionid这种问题,就搞一次其他请求先于这个接口,把重要的接口放在后面就肯定有jsessionid啦。

2)当再次请求的时候(非首次请求),浏览器会在请求头里将cookie发送给服务器(每次请求都是这样)

(JSESSIONID=ghco9xdnaco31gmafukxchph)


image.png

不难发现这个的jsessionid和上面的jsessionid是一样的

3)为什么除了首次请求之外每次请求都会发送这个cookie呢(在这里确切地说是发送这个jsessionid)?

事实上当用户访问服务器的时候会为每一个用户开启一个session,浏览器是怎么判断这个session到底是属于哪个用户呢?jsessionid的作用就体现出来了:jsessionid就是用来判断当前用户对应于哪个session。换句话说服务器识别session的方法是通过jsessionid来告诉服务器该客户端的session在内存的什么地方。

事实上jsessionid ==request.getSession().getId()

4)总结,jsessionid的工作流程可以简单用下面的图表示:

image.png

同步方式:

方式一:客户端将cookie传给H5

  • 客户端:将登陆时从服务器取得的cookie传给html。
  • html:ajax从参数中取出客户端传来的cookie,ajax发请求时将客户端传来cookie设置到请求头中。

ajax修改cookie的方式

$.ajax({
   headers: {'Cookie' : document.cookie },
   url: "sub.domain.com",
   success: function(){}
})
缺点:
  1. 兼容性差,多数浏览器为了安全起见,都做了禁止修改请求中的cookie的限制。比如iOS的WebView会拦截ajax修改的cookie。
  2. 繁琐,每次请求都需要拼接cookie作为参数,比较繁琐。

方式二:将cookie同步到WebView(推荐)

原理分析:

WebView的cookie机制

WebView是基于webkit内核的UI控件,相当于一个浏览器客户端。它会在本地维护每次会话的cookie(保存在data/data/package_name/app_WebView/Cookies.db)。

当WebView加载URL的时候,WebView会从本地读取该URL对应的cookie,并携带该cookie与服务器进行通信。
WebView通过android.webkit.CookieManager类来维护cookie。CookieManager是WebView的cookie管理类。

 /**
     * 将cookie同步到WebView
     *
     * @param url    WebView要加载的url
     * @param cookie 要同步的cookie
     * @return true 同步cookie成功,false同步cookie失败
     * @Author JPH
     */
    public void syncCookie(String url, List cookies) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            CookieSyncManager.createInstance(this);
        }
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        cookieManager.removeAllCookie();
        StringBuffer sb = new StringBuffer();
 
        for (Cookie cookie : cookies) {
            String cookieName = cookie.getName();
            String cookieValue = cookie.getValue();
            if (!TextUtils.isEmpty(cookieName)
                    && !TextUtils.isEmpty(cookieValue)) {
                sb.append(cookieName + "=");
                sb.append(cookieValue + ";");
            }
        }
 
 
        String[] cookie = sb.toString().split(";");
        for (int i = 0; i < cookie.length; i++) {
            Log.i(TAG,"cookie:"+cookie[i]);
            cookieManager.setCookie(url, cookie[i]);// cookies是在HttpClient中获得的cookie
        }
        CookieSyncManager.getInstance().sync();
    }

如果设置成功,通过cookieManager.getCookie(url)方法就可取得刚才设置的cookie,如果两次设置cookie的url相同,则CookieManager会将上一次设置的cookie覆盖,已达到更新的效果。
下面我们查看一下Cookie数据库中发生的变化。

提示:
1. 同步cookie要在WebView加载url之前,否则WebView无法获得相应的cookie,也就无法通过验证。
2. 每次登录成功后都需要调用”syncCookie”方法将cookie同步到WebView中,同时也达到了更新WebView的cookie。如果登录后没有及时将cookie同步到WebView可能导致WebView拿的是旧的session id和服务器进行通信。

优点:
  1. 方便,只需要在登陆后将cookie同步到WebView即可,省去了每次请求都需要设置一次的繁琐。
  2. 兼容性好,因为是系统原生支持的,所以兼容性自然比方式一要好,不存在cookie被拦截的问题。

同步Cookie到腾讯X5 WebView

很多人在使用它腾讯提供的X5服务器,来替代Android原生的WebView,如果你正是使用腾讯X5内核的话,同样NoHttp也支持Cookie同步。

步骤和上面原生WebView没区别,但是要注意几点:

1、继承不是系统的android.webkit.WebView,而是com.tencent.smtt.sdk.WebView。
2、同步到X5内核时不再是android.webkit.CookieManagerr,而是com.tencent.smtt.sdk.CookieManager。
3、同步到X5内核时不再是android.webkit.CookieSyncManager,而是com.tencent.smtt.sdk.CookieSyncManager。

你可能感兴趣的:(android webview同步cookie)