Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maintain cookie session in Android

Okay, I have an android application that has a form in it, two EditText, a spinner, and a login button. The user selects the service from the spinner, types in their user name and password, and clicks login. The data is sent via POST, a response is returned, it's handled, a new WebView is launched, the html string generated from the response is loaded, and I have the home page of whatever service the user selected.

That's all well and good. Now, when the user clicks on a link, the login info can't be found, and the page asks the user to login again. My login session is being dropped somewhere, and I'm not certain how to pass the info from the class that controls the main part of my app to the class that just launches the webview activity.

The onClick handler from the form login button:

private class FormOnClickListener implements View.OnClickListener {

    public void onClick(View v) {

        String actionURL, user, pwd, user_field, pwd_field;

        actionURL = "thePageURL";
        user_field = "username"; //this changes based on selections in a spinner
        pwd_field = "password"; //this changes based on selections in a spinner
        user = "theUserLogin";
        pwd = "theUserPassword";

        List<NameValuePair> myList = new ArrayList<NameValuePair>();
        myList.add(new BasicNameValuePair(user_field, user)); 
        myList.add(new BasicNameValuePair(pwd_field, pwd));

        HttpParams params = new BasicHttpParams();
        DefaultHttpClient client = new DefaultHttpClient(params);
        HttpPost post = new HttpPost(actionURL);
        HttpResponse response = null;
        BasicResponseHandler myHandler = new BasicResponseHandler();
        String endResult = null;

        try { post.setEntity(new UrlEncodedFormEntity(myList)); } 
        catch (UnsupportedEncodingException e) { e.printStackTrace(); } 

        try { response = client.execute(post); } 
        catch (ClientProtocolException e) { e.printStackTrace(); } 
        catch (IOException e) { e.printStackTrace(); }  

        try { endResult = myHandler.handleResponse(response); } 
        catch (HttpResponseException e) { e.printStackTrace(); } 
        catch (IOException e) { e.printStackTrace(); }

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

       Intent myWebViewIntent = new Intent(MsidePortal.this, MyWebView.class);
       myWebViewIntent.putExtra("htmlString", endResult);
       myWebViewIntent.putExtra("actionURL", actionURL);
       startActivity(myWebViewIntent);
    }
}

And here is the WebView class that handles the response display:

public class MyWebView extends android.app.Activity {

    private class MyWebViewClient extends WebViewClient {

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

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.web);

        MyWebViewClient myClient = new MyWebViewClient();
        WebView webview = (WebView)findViewById(R.id.mainwebview);
        webview.getSettings().setBuiltInZoomControls(true); 
        webview.getSettings().setJavaScriptEnabled(true); 
        webview.setWebViewClient(myClient);

        Bundle extras = getIntent().getExtras();
        if(extras != null) 
        {
            // Get endResult
            String htmlString = extras.getString("htmlString");
            String actionURL = extras.getString("actionURL");

            Cookie sessionCookie = MsidePortal.cookie;
            CookieSyncManager.createInstance(this);
            CookieManager cookieManager = CookieManager.getInstance();
            if (sessionCookie != null) {
                cookieManager.removeSessionCookie();
                String cookieString = sessionCookie.getName()
                        + "=" + sessionCookie.getValue()
                        + "; domain=" + sessionCookie.getDomain();
                cookieManager.setCookie(actionURL, cookieString);
                CookieSyncManager.getInstance().sync();
            }  

            webview.loadDataWithBaseURL(actionURL, htmlString, "text/html", "utf-8", actionURL);}
        }
    }
}

I've had mixed success implementing that cookie solution. It seems to work for one service I log into that I know keeps the cookies on the server (old, archaic, but it works and they don't want to change it.) The service I'm attempting now requires the user to keep cookies on their local machine, and it does not work with this setup.

Any suggestions?

like image 677
datguywhowanders Avatar asked Jun 14 '10 16:06

datguywhowanders


People also ask

Are cookies used to maintain session?

Using session cookies to hold session information is a method for maintaining plug-in session state. The server packages the state information for a particular client in a cookie and sends it to the client's browser.

What is a cookie in Android?

Cookies are files created by websites you visit. They make your online experience easier by saving browsing information. With cookies, sites can keep you signed in, remember your site preferences, and give you locally relevant content.

Is cookie dependent on session?

Sessions are cookies dependent, whereas Cookies are not dependent on Session. The session ends when the user closes the browser or logout from the application, whereas Cookies expire at the set time. A session can store as much data as a user want, whereas Cookies have a limited size of 4KB.

Do session cookies expire?

Session cookies expire once you log off or close the browser. They are only stored temporarily and are destroyed after leaving the page. They are also known as transient cookies, non-persistent cookies, or temporary cookies.


2 Answers

You need to keep the cookie from one call to another. Instead of creating a new DefaultHttpClient, use this builder:

private Object mLock = new Object();
private CookieStore mCookie = null;
/**
 * Builds a new HttpClient with the same CookieStore than the previous one.
 * This allows to follow the http session, without keeping in memory the
 * full DefaultHttpClient.
 * @author Régis Décamps <[email protected]>
 */
private HttpClient getHttpClient() {
        final DefaultHttpClient httpClient = new DefaultHttpClient();
        synchronized (mLock) {
                if (mCookie == null) {
                        mCookie = httpClient.getCookieStore();
                } else {
                        httpClient.setCookieStore(mCookie);
                }
        }
        return httpClient;
}

And keep the Builder class as a field of your application.

like image 185
rds Avatar answered Sep 22 '22 14:09

rds


Use this in url login Activity

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

    Cookie sessionCookie = cookie;

    if (sessionCookie != null) {
        String cookieString = sessionCookie.getName() + "="
                + sessionCookie.getValue() + "; domain="
                + sessionCookie.getDomain();
        cookieManager
                .setCookie("www.mydomain.com", cookieString);
        CookieSyncManager.getInstance().sync();
    }
like image 39
suraj jain Avatar answered Sep 18 '22 14:09

suraj jain