Android HttpClient+WebView同期セッションIdとクッキー

8701 ワード

AndroidクライアントがhttpClientまたはhttpUrlConnectionでログインした後、ログイン状態をwebViewに同期させるには、クッキーの同期が必要です
一.クッキー同期方式
次はログインスレッドです.
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);
        }

    }