android WebView登录状态session id 和cookie同步

上次说到的WebView还有一个遇到的比较难一点的问题没有回答上来。主要是关于在用webview的时候无法保存登录状态,下次打开网页还是会打开登录界面。有两三个朋友同时问到我这个问题,而刚刚好我也不懂,也正在学习。而且刚好也找到可以学习的路径并且真实可用。废话少说,先标明出处,小心被打
本文转载自:http://f059074251.iteye.com/blog/2184072
作者:http://f059074251.iteye.com/ f059074251

android客户端通过httpClient或者httpUrlConnection进行登录后,为了把登录状态同步到webView中,这时需要进行cookie的同步

一.cookie同步方式

下面是登录线程:

public class LoginThread extends Thread{

private Handler loginHandler;

public  LoginThread(Handler loginHandler) {
    this.loginHandler = loginHandler;
}
@Override
public void run()
{
    List<String> cookieLst = new ArrayList<String>();
    HttpParams httpParams = new BasicHttpParams();
    ConnManagerParams.setMaxTotalConnections(httpParams, 5);
    ConnManagerParams.setTimeout(httpParams, 15*1000);
    HttpConnectionParams.setSoTimeout(httpParams, 10*1000);
    HttpConnectionParams.setTcpNoDelay(httpParams, true);
    HttpPost httpPost = new HttpPost("http://192.168.1.107/cookie/login.php");
    List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
    nvPairs.add(new BasicNameValuePair("name", "lisi"));
    nvPairs.add(new BasicNameValuePair("age","22"));
    nvPairs.add(new BasicNameValuePair("gender", "男"));

    try {
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvPairs, HTTP.UTF_8);
        httpPost.setEntity(entity);
        HttpClient httpClient =  new DefaultHttpClient();
        HttpResponse httpResponse = httpClient.execute(httpPost);
        if(httpResponse!=null && httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
        {
           String content = EntityUtils.toString(httpResponse.getEntity());
           Log.d("LOGIN", content);
           Header[] allHeaders = httpResponse.getAllHeaders();
           if(allHeaders!=null)
           {
               //获取cookie的第一种方式
               for (Header header : allHeaders)
               {
                   Log.d("LOGIN", header.getName()+"="+header.getValue());
                   if("Set-Cookie".equalsIgnoreCase(header.getName()))
                   {
                       cookieLst.add(header.getValue());
                   }
                }
           }
           //获取cookie的第二种方式
           AbstractHttpClient abstractHttpClient = (AbstractHttpClient) httpClient;
           CookieStore cookieStore = abstractHttpClient.getCookieStore();
           List<Cookie> cookies = cookieStore.getCookies();
           for (Cookie cookie : cookies)
           {
               Log.d("LOGIN-COOKIE", cookie.getName()+"="+cookie.getValue()+",path="+cookie.getPath()+",domain="+cookie.getDomain()+",expires="+cookie.getExpiryDate());
            }

           if(loginHandler!=null)
           {
               Message msg = new Message();
               msg.obj = cookieLst;
               msg.what = 200;
               msg.setTarget(loginHandler);
               msg.sendToTarget();
           }
        }
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}
下面是WebView主页面Activity

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class Main extends Activity implements DownloadListener {

private WebView mWebView;

//extraHeaders经测试不可以同步cookie
private Map<String, String> extraHeaders;

private final String TAG = "WEB_VIEW";

private final Handler loginHandler = new Handler(){

    @Override
    public void handleMessage(Message msg) {

        if(msg.what==200)
        {
            List<String> cookies =  (List<String>) msg.obj;
            if(cookies!=null)
            {  
                syncCookieToWebView(cookies);
                mWebView.loadUrl("http://192.168.1.107/cookie/read.php");
            }
        }else{
            super.handleMessage(msg);
        }
    }

};

@SuppressLint("SetJavaScriptEnabled")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mWebView = (WebView) findViewById(R.id.main_webview);
    WebSettings settings = mWebView.getSettings();
    settings.setAppCacheEnabled(true);
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);
    settings.setGeolocationEnabled(true);
    settings.setUseWideViewPort(true);
    settings.setSaveFormData(true);
    settings.setSavePassword(true);
    settings.setSupportZoom(false);
    settings.setLoadsImagesAutomatically(true);
    settings.setBlockNetworkImage(false);
    if(android.os.Build.VERSION.SDK_INT>=11)
    {
        settings.setEnableSmoothTransition(true);
    }
    settings.setJavaScriptCanOpenWindowsAutomatically(false);
    settings.setAllowFileAccess(false);
    settings.setJavaScriptEnabled(true);
    String userAgent = settings.getUserAgentString();
    Log.d(TAG, userAgent);
    if(android.os.Build.VERSION.SDK_INT>=14)
    {
        mWebView.setFitsSystemWindows(true);
    }
    if(mWebView.isHardwareAccelerated())
    {
        mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
    }
    mWebView.setKeepScreenOn(true);
    extraHeaders = new IdentityHashMap<String, String>();

    mWebView.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(view!=null && !TextUtils.isEmpty(url))
            {
                extraHeaders.put("control-cache", "no-cache,private");
                extraHeaders.put("pragma", "no-cache,no-store");
                extraHeaders.put("expires", "0");
                view.loadUrl(url, extraHeaders);
                return true;
            }
            return super.shouldOverrideUrlLoading(view, url);
        }
    });

    mWebView.setDownloadListener(this);

    //mWebView.loadUrl("http://shouji.baidu.com/software/?from=web_alad_multi");
    new LoginThread(loginHandler).start();
}
//销毁webView
@Override
protected void onDestroy() {
    super.onDestroy();
    mWebView.clearFormData();
    mWebView.clearHistory();
    mWebView.destroy();
}

//监听文件下载,WebView不会自动下载,需要我们自己构建下载代码
@Override
public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength)
{
    Log.d(TAG, "url="+url);
    Log.d(TAG, "userAgent="+url);
    Log.d(TAG, "contentDisposition="+contentDisposition);
    Log.d(TAG, "mimetype="+mimetype);
    Log.d(TAG, "contentLength="+contentLength);

    //第一种下载方式是 自定义的http工具类
    //new DownloadThread(url,contentDisposition,mimetype,contentLength).start();


    //第二种下载方式是调用系统的webView,具有默认的进度条
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse(url));
    startActivity(intent);

}
/**
 * cookie同步
 */
private void syncCookieToWebView(List<String> cookies)
{
    CookieSyncManager.createInstance(Main.this);
    CookieManager cm = CookieManager.getInstance();
    cm.setAcceptCookie(true);
    if(cookies!=null)
    {
        for (String cookie : cookies)
        {
        cm.setCookie("http://192.168.1.107:80",cookie);//注意端口号和域名,这种方式可以同步所有cookie,包括sessionid
         }
    }
    CookieSyncManager.getInstance().sync();
}

}

二.注意:平时开发中Cookie同步是最佳选项,但这并不意味着一定需要使用cookie同步,我们可以使用 token+用户id+登录时间校验码 进行同步登录

三.对于使用javaInterface进行同步登录的问题

javaInterface风险性很高,如果android平台是 4.2+比较安全,但4.2以下版本,安全性不容乐观,比如通过反射造成硬盘被读写的可能性很高!

在android 4.2中增加了 @javainterface注解,并且将公开的方法异步化,这样有效的控制了某些没必要公开的方法被无意间作为接口公开,导致js发射到硬盘的读写io类,从而发生文件被窃取,垃圾文件堆积,有害文件被下载等问题!

四.目前来说让所有人使用 4.2+以上版本可能性不大,但尽量少使用javainterface,转而使用 协议的方式,所谓协议,就是通信协议,我们可以分析url参数,从而进行webView和native代码的通信

mWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {

        //捕获url的参数值

        if(url.indexOf("login")>=0)
        {
            //客户端代码执行某部分操作----->执行完毕后通过url参数把执行结果返回webView

        }else if(url.indexOf("userCenter")>=0){
            //客户端代码执行某部分操作----->执行完毕后通过url参数把执行结果返回webView
        }
        return super.shouldOverrideUrlLoading(view, url);
        }
    });

当然,javainterface不推荐,但完全可以使用

?
1
view.loadUrl(“javascript:dosometing(“+”’参数’”+”)”);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值