文档章节

android HttpClient+WebView 同步cookie

IamOkay
 IamOkay
发布于 2014/12/29 09:33
字数 1085
阅读 1758
收藏 15

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


参考:http://segmentfault.com/a/1190000002877843


一.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();
			
			 //Cookie可能获取不到,因此有必要调用浏览器兼容模式
			HttpClientParams.setCookiePolicy(httpClient.getParams(), CookiePolicy.BROWSER_COMPATIBILITY);  
			   
			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不推荐,但完全可以使用

view.loadUrl("javascript:dosometing("+"'参数'"+")");


-------------------------------2015-04-30-更新,从webView读取cookie--------------------------------

private class MyWebViewClient extends WebViewClient {

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            webview.loadUrl(url);
            return true;
        }

        public void onPageFinished(WebView view, String url) {
            CookieManager cookieManager = CookieManager.getInstance();
            String CookieStr = cookieManager.getCookie(url);
            Log.e("sunzn", "Cookies = " + CookieStr);
            super.onPageFinished(view, url);
        }

    }



© 著作权归作者所有

IamOkay

IamOkay

粉丝 203
博文 483
码字总数 403198
作品 0
海淀
程序员
私信 提问
加载中

评论(1)

奈萌摸尔
感谢博主的分享,用你的方法 解决了困扰我好几天的问题,非常感谢博主!给赞!!
三星G9200无法设置WebView中的cookie

手机Android版本6.0.1,WebView初始过程中用户数据同步,请求返回cookie,其他手机可以正常同步登录,只有三星手机无法同步,打印日志查看cookie设置不成功,cookie值为null。WebView设置正常...

Mr_Darly
2016/07/04
309
1
Android最新面试实战总结

所谓,君子性非异也,善假于物也!~ 那么,本文意在给大家提供快速、全面、高效的面试解决方案; 为大家节约寻找面试、笔试答案的时间; 让阅读本文或收藏本文的开发者成为Android面试场上的最...

小猪看流星
2017/10/13
0
0
Android 支持网络协议以及简单用法

Android对网络编程提供3中接口,即:Java接口,Apache接口,Android接口。Android提供了对HTTP,SSL,Cookie,DHCP等协议的封装,并支持套接字编程,同时对UTI也提供了支持。另外,还提供了连...

Drealin
2012/09/19
956
0
Firefox 62 正式发布,调整 Windows 上的 UI 并改进渲染

Firefox 62 已发布,桌面版和 Android 版同步更新。在该版本中,Mozilla 为新标签页面引入了 UI 刷新(UI refresh)、增强性能以加快浏览速度,以及一些安全增强功能。 在性能方面,Windows 用...

达尔文
2018/09/06
3.3K
24
Android 控件WebView设置Cookie

01. 设置方式 同步的问题很常见,网上搜到的解决方法基本类似。 这里简单说明: 参数中的URL在使用过程中基本是域名。例如就可以使 Cookie列表的获取根据自己项目的存储方式不同而不同。例如...

丁佳辉
2017/11/02
228
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 是所有基于 Spring 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。

Springboot框架搭建相关 Spring Boot 是所有基于 Spring 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。 什么是 Spring Boo...

AndLong
22分钟前
3
0
好程序员云计算学习路线分享软件包管理

好程序员云计算学习路线分享软件包管理,安装/查询/卸载 一、软件的类型 A. 源码包 需要编译 nginx-1.12.1.tar.gz B. 二进制包 已编译 mysql-community-common-5.7.12-1.el7.x86_64.rpm 常见...

好程序员官方
24分钟前
1
0
阿里巴巴小程序繁星计划 9月27日有话要说

2019年9月27日,阿里巴巴小程序繁星计划峰会将于杭州云栖小镇召开。这是自今年3月阿里巴巴正式对外宣布全面开启小程序发展战略,阿里云携手支付宝、淘宝、钉钉、高德联合发布“阿里巴巴小程序...

Mr_zebra
27分钟前
4
0
centos下搭建Jenkins持续集成环境(安装jenkins)

centos下搭建Jenkins持续集成环境(安装jenkins) 1、安装JDK yum install -y java 2、安装jenkins 添加Jenkins库到yum库,Jenkins将从这里下载安装。 1 wget -O /etc/yum.repos.d/jenkins.rep...

linjin200
29分钟前
4
0
JDK1.8.0_181的无限制强度加密策略文件变动

JDK1.8.0_151后的版本无需去官网下载 local_policy.jar US_export_policy.jar这个jar包,只需要修改Java\jdk1.8.0_181\jre\lib\security这目录下的java.security文件配置即可。 随着越来越多...

葉者
31分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部