Android HttpClient+WebView同期セッションIdとクッキー
8701 ワード
AndroidクライアントがhttpClientまたはhttpUrlConnectionでログインした後、ログイン状態をwebViewに同期させるには、クッキーの同期が必要です
一.クッキー同期方式
次はログインスレッドです.
次はWebViewホームページActivityです
二.注意:通常開発ではCookie同期が最適ですが、必ずしもcookie同期を使用する必要はありません.token+ユーザーid+ログイン時間チェックコードを使用して同期ログインできます.
三.JavaInterfaceによる同期ログインの問題
JAvaInterfaceはリスクが高く、androidプラットフォームが4.2+なら安全ですが、4.2以下のバージョンでは、反射によってハードディスクが読み書きされる可能性が高いなど、安全性は楽観的ではありません.
Android 4.2に@javainterface注釈を追加し、公開の方法を非同期化することで、公開する必要のない方法が何気なくインタフェースとして公開されることを効果的に制御し、jsがハードディスクの読み書きioクラスに送信され、ファイルが盗まれ、ゴミファイルが堆積し、有害なファイルがダウンロードされるなどの問題が発生する.
四.現在、4.2+以上のバージョンをすべての人に使用させる可能性は低いが、javainterfaceをできるだけ少なく使用し、プロトコルを使用する方法に変える.プロトコルとは、通信プロトコルであり、urlパラメータを分析してwebViewとnativeコードの通信を行うことができる.
もちろんjavainterfaceはお勧めしませんが、完全に使えます
------------------------------------2015-04-30-更新、webViewから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);
}
}