Android: saving a server session with a cookie when making HTTP calls

Server-side sessions are stored in a database and maintained using cookies. Thus, each client must have a valid cookie corresponding to a session in the database.

and on the Android side:

DefaultHttpClient client = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); HttpResponse response = client.execute(httppost); 

If I use the same client for all server calls, the client will take care of these cookies.

But the problem is that when the client is destroyed due to the memory needed by the device, cookies are lost and any subsequent server calls do not work.

Is there a way to make HttpClient persistent? Or what is the usual way to support cookies on the android side.

+6
source share
4 answers

The β€œright” way to do this is to implement CookieHandler: http://developer.android.com/reference/java/net/CookieHandler.html

The easiest way to do this is to extend the application and put it in your onCreate () applications:

 CookieHandler.setDefault(new CookieManager()); 

PLEASE NOTE:. Only DEFAULT CookieManger will be implemented. By default, CookieManger will manage cookies for all of your HTTP requests for a specific session of your application. However, it does not have any means of storing cookies the next time you use the application.

To do this, you need to write your own cookie manager by implementing CookieStore: http://developer.android.com/reference/java/net/CookieStore.html

Here is an example implementation of CookieStore that I used in an application that is currently on the Google Play store:

 package com.touchvision.util; import java.net.CookieStore; import java.net.HttpCookie; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.util.Log; import com.touchvision.Config; /* * This is a custom cookie storage for the application. This * will store all the cookies to the shared preferences so that it persists * across application restarts. */ public class TvCookieStore implements CookieStore { private static final String LOGTAG = "TV-TvCookieStore"; /* * The memory storage of the cookies */ private Map<String, Map<String,String>> mapCookies = new HashMap<String, Map<String,String>>(); /* * The instance of the shared preferences */ private final SharedPreferences sharedPrefs; /* * @see java.net.CookieStore#add(java.net.URI, java.net.HttpCookie) */ public void add(URI uri, HttpCookie cookie) { String domain = cookie.getDomain(); // Log.i(LOGTAG, "adding ( " + domain +", " + cookie.toString() ); Map<String,String> cookies = mapCookies.get(domain); if (cookies == null) { cookies = new HashMap<String, String>(); mapCookies.put(domain, cookies); } cookies.put(cookie.getName(), cookie.getValue()); if (cookie.getName().startsWith("SPRING_SECURITY") && !cookie.getValue().equals("")){ // Log.i(LOGTAG, "Saving rememberMeCookie = " + cookie.getValue() ); // Update in Shared Preferences Editor e = sharedPrefs.edit(); e.putString(Config.PREF_SPRING_SECURITY_COOKIE, cookie.toString()); e.commit(); // save changes } } /* * Constructor * * @param ctxContext the context of the Activity */ public TvCookieStore(Context ctxContext) { // Log.i(LOGTAG, "constructor()"); sharedPrefs = ctxContext.getSharedPreferences(Config.SHARED_PREF_NAME, Context.MODE_PRIVATE); } /* * @see java.net.CookieStore#get(java.net.URI) */ public List<HttpCookie> get(URI uri) { List<HttpCookie> cookieList = new ArrayList<HttpCookie>(); String domain = uri.getHost(); // Log.i(LOGTAG, "getting ( " + domain +" )" ); Map<String,String> cookies = mapCookies.get(domain); if (cookies == null) { cookies = new HashMap<String, String>(); mapCookies.put(domain, cookies); } for (Map.Entry<String, String> entry : cookies.entrySet()) { cookieList.add(new HttpCookie(entry.getKey(), entry.getValue())); // Log.i(LOGTAG, "returning cookie: " + entry.getKey() + "="+ entry.getValue()); } return cookieList; } /* * @see java.net.CookieStore#removeAll() */ public boolean removeAll() { // Log.i(LOGTAG, "removeAll()" ); mapCookies.clear(); return true; } /* * @see java.net.CookieStore#getCookies() */ public List<HttpCookie> getCookies() { Log.i(LOGTAG, "getCookies()" ); Set<String> mapKeys = mapCookies.keySet(); List<HttpCookie> result = new ArrayList<HttpCookie>(); for (String key : mapKeys) { Map<String,String> cookies = mapCookies.get(key); for (Map.Entry<String, String> entry : cookies.entrySet()) { result.add(new HttpCookie(entry.getKey(), entry.getValue())); Log.i(LOGTAG, "returning cookie: " + entry.getKey() + "="+ entry.getValue()); } } return result; } /* * @see java.net.CookieStore#getURIs() */ public List<URI> getURIs() { Log.i(LOGTAG, "getURIs()" ); Set<String> keys = mapCookies.keySet(); List<URI> uris = new ArrayList<URI>(keys.size()); for (String key : keys){ URI uri = null; try { uri = new URI(key); } catch (URISyntaxException e) { e.printStackTrace(); } uris.add(uri); } return uris; } /* * @see java.net.CookieStore#remove(java.net.URI, java.net.HttpCookie) */ public boolean remove(URI uri, HttpCookie cookie) { String domain = cookie.getDomain(); Log.i(LOGTAG, "remove( " + domain +", " + cookie.toString() ); Map<String,String> lstCookies = mapCookies.get(domain); if (lstCookies == null) return false; return lstCookies.remove(cookie.getName()) != null; } } 

The above custom CookieStore uses SharedPreferences to save cookies. You implement the above class, similar to how you would use the default CookieManager in your application class, but the line will look like this:

 CookieHandler.setDefault( new CookieManager( new TvCookieStore(this), CookiePolicy.ACCEPT_ALL)); 

As you can see, the only cookie that really cared about saving was the Spring Cookie security (we used the Spring Framework on the server side). Obviously, your code will be different from your specific needs.

One more note: I tried many times to do what you are doing and handle the storage of cookies in my http client class. It was just a headache. Give this strategy a shot.

+7
source

It may not be cookies, but it may be helphttp: //developer.android.com/reference/android/accounts/package-summary.html

0
source

Try entering the code:

 public static List<Cookie> cookies; cookies = httpclient.getCookieStore().getCookies(); if (cookies != null) { CookieSyncManager.createInstance(MainActivity.activity); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); for (Cookie cookie : cookies) { Cookie sessionInfo = cookie; String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain(); cookieManager.setCookie( domainUrl,cookieString); CookieSyncManager.getInstance().sync(); } } 
0
source

Try this way. Hope this helps you.

 public static List<Cookie> cookies; public static List<Cookie> sync(String url) { CookieManager cookieManager = CookieManager.getInstance(); if (cookieManager == null) return null; RFC2109Spec cookieSpec = new RFC2109Spec(); String rawCookieHeader = null; try { URL parsedURL = new URL(url); rawCookieHeader = cookieManager.getCookie(parsedURL.getHost()); if (rawCookieHeader == null) return null; int port = parsedURL.getPort() == -1 ? parsedURL.getDefaultPort() : parsedURL.getPort(); CookieOrigin cookieOrigin = new CookieOrigin(parsedURL.getHost(), port, "/", false); List<Cookie> cookies = cookieSpec.parse(new BasicHeader( "set-cookie", rawCookieHeader), cookieOrigin); return cookies; } catch (Exception e) { } return null; } public void sync() { if (cookies != null) { CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); for (Cookie cookie : cookies) { Cookie sessionInfo = cookie; String cookieString = sessionInfo.getName() + "=" + sessionInfo.getValue() + "; domain=" + sessionInfo.getDomain(); cookieManager.setCookie("yourDomainUrl", cookieString); CookieSyncManager.getInstance().sync(); } } } public static DefaultHttpClient getHttpclient() { HttpParams httpParameters = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParameters, 30000); HttpConnectionParams.setSoTimeout(httpParameters, 30000); DefaultHttpClient httpclient = new DefaultHttpClient(httpParameters); if (cookies != null) { int size = cookies.size(); for (int i = 0; i < size; i++) { httpclient.getCookieStore().addCookie(cookies.get(i)); } } else { cookies = sync("yourDomain"); if (cookies != null) { int size = cookies.size(); for (int i = 0; i < size; i++) { httpclient.getCookieStore().addCookie(cookies.get(i)); } } } httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "android"); return httpclient; } 

How to use?

 DefaultHttpClient client =getHttpclient(); HttpPost httppost = new HttpPost(url); HttpResponse response = client.execute(httppost); try { cookies = httpclient.getCookieStore().getCookies(); sync(); } catch (Exception e) { } 
0
source

Source: https://habr.com/ru/post/955034/


All Articles