3
votes

After many, many hours I managed to figure out how to share cookies betwen my httpclient and my webview. My problem right now is that for some reason my session cookie is not being shared.

In the android docs I found: public void setCookie (String url, String value) Since: API Level 1 Set cookie for a given url. The old cookie with same host/path/name will be removed. The new cookie will be added if it is not expired or it does not have expiration which implies it is session cookie.

Thing is I share a cookie that has expiration set and it works. Anyone have any ideas why my session cookie is not shared or if it is in fact because setCookie can't do it, how can I do it in a different way.

Here is my code:

    package mds.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class Home extends Activity {



    public static final String LOG_TAG = "Droidnova";

    private class HelloWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

    private String tmDevice;
    private String sid;
    private String url;
    public static Cookie cookie = null;


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        CookieSyncManager.createInstance(this);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);

        final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
        tmDevice = "blabla" + tm.getDeviceId();

        postData();

        url = "mywebsite="+sid.substring(5); 

        Log.d(LOG_TAG, "cookie value: " + cookie);

        if (cookie != null) {
            cookieManager.removeSessionCookie();
            String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();
            cookieManager.setCookie(cookie.getDomain(), cookieString);
            CookieSyncManager.getInstance().sync();
        }

        setContentView(R.layout.web);
        WebView myWebView = (WebView) findViewById(R.id.webview);
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.setWebViewClient(new HelloWebViewClient());
        myWebView.loadUrl(url);
    }

    public void postData() {
        // Create a new HttpClient and Post Header
        DefaultHttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("my website");

        try {
            // Add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("uid", tmDevice));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);

            inputStreamToString(response.getEntity().getContent());


            List<Cookie> cookies = httpclient.getCookieStore().getCookies();
            if (!cookies.isEmpty()) {
                for (int i = 0; i < cookies.size(); i++) {
                    cookie = cookies.get(i);
                }
            }

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
        } catch (IOException e) {
            // TODO Auto-generated catch block
        }

   }

    private void inputStreamToString(InputStream is) {
        String line = "";
        StringBuilder total = new StringBuilder();

        // Wrap a BufferedReader around the InputStream
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));

        // Read response until the end
        try {
            while ((line = rd.readLine()) != null) { 
                total.append(line); 
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        sid = total.toString();         
    }

}
1

1 Answers

1
votes

Note, this is not a solution, it's a workaround, provided you have access to the code of the page.

Instead of passing the cookie to webView you can pass a POST value of the cookie:

String postData = cookie.getName() + "=" + cookie.getValue();
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.setWebViewClient(new HelloWebViewClient());
myWebView.postUrl(loadUrl,EncodingUtils.getBytes(postData, "BASE64") );

On the website in the authorization mechanism you have to check for the POST data as well as the session.