Skip to content

Instantly share code, notes, and snippets.

@lezorich
Last active September 20, 2022 02:23
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save lezorich/8f3f3a54f07515881581 to your computer and use it in GitHub Desktop.
Save lezorich/8f3f3a54f07515881581 to your computer and use it in GitHub Desktop.
Android basic persistent cookie manager for Volley. This cookie store wraps the default CookieManager store to store the session cookie. It use's Gson to json serialize the cookie and store it as a json string in SharedPreferences.
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Lukas Zorich
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.URI;
import java.util.List;
/**
* Repository for cookies. CookieManager will store cookies of every incoming HTTP response into
* CookieStore, and retrieve cookies for every outgoing HTTP request.
* <p/>
* Cookies are stored in {@link android.content.SharedPreferences} and will persist on the
* user's device between application session. {@link com.google.gson.Gson} is used to serialize
* the cookies into a json string in order to be able to save the cookie to
* {@link android.content.SharedPreferences}
* <p/>
* Created by lukas on 17-11-14.
*/
public class PersistentCookieStore implements CookieStore {
/**
* The default preferences string.
*/
private final static String PREF_DEFAULT_STRING = "";
/**
* The preferences name.
*/
private final static String PREFS_NAME = PersistentCookieStore.class.getName();
/**
* The preferences session cookie key.
*/
private final static String PREF_SESSION_COOKIE = "session_cookie";
private CookieStore mStore;
private Context mContext;
/**
* @param context The application context
*/
public PersistentCookieStore(Context context) {
// prevent context leaking by getting the application context
mContext = context.getApplicationContext();
// get the default in memory store and if there is a cookie stored in shared preferences,
// we added it to the cookie store
mStore = new CookieManager().getCookieStore();
String jsonSessionCookie = getJsonSessionCookieString();
if (!jsonSessionCookie.equals(PREF_DEFAULT_STRING)) {
Gson gson = new Gson();
HttpCookie cookie = gson.fromJson(jsonSessionCookie, HttpCookie.class);
mStore.add(URI.create(cookie.getDomain()), cookie);
}
}
@Override
public void add(URI uri, HttpCookie cookie) {
if (cookie.getName().equals("sessionid")) {
// if the cookie that the cookie store attempt to add is a session cookie,
// we remove the older cookie and save the new one in shared preferences
remove(URI.create(cookie.getDomain()), cookie);
saveSessionCookie(cookie);
}
mStore.add(URI.create(cookie.getDomain()), cookie);
}
@Override
public List<HttpCookie> get(URI uri) {
return mStore.get(uri);
}
@Override
public List<HttpCookie> getCookies() {
return mStore.getCookies();
}
@Override
public List<URI> getURIs() {
return mStore.getURIs();
}
@Override
public boolean remove(URI uri, HttpCookie cookie) {
return mStore.remove(uri, cookie);
}
@Override
public boolean removeAll() {
return mStore.removeAll();
}
private String getJsonSessionCookieString() {
return getPrefs().getString(PREF_SESSION_COOKIE, PREF_DEFAULT_STRING);
}
/**
* Saves the HttpCookie to SharedPreferences as a json string.
*
* @param cookie The cookie to save in SharedPreferences.
*/
private void saveSessionCookie(HttpCookie cookie) {
Gson gson = new Gson();
String jsonSessionCookieString = gson.toJson(cookie);
SharedPreferences.Editor editor = getPrefs().edit();
editor.putString(PREF_SESSION_COOKIE, jsonSessionCookieString);
editor.apply();
}
private SharedPreferences getPrefs() {
return mContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
}
@lezorich
Copy link
Author

To use the cookie store just do:

CookieManager cookieManager = new CookieManager(new PersistentCookieStore(mContext), CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager);

@lezorich
Copy link
Author

@AnixPasBesoin, I have just made an update of the gist. Try to use it now, and tell me if you don't understand something :)

@arindamdawn-zz
Copy link

Where shall I include this :
CookieManager cookieManager = new CookieManager(new PersistentCookieStore(mContext), CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager); ??

Shall I include it after calling the request queue and making the json object request?

@lezorich
Copy link
Author

@arindamrockz: Yes, you should included before calling the request queue. I always included at the start of the application.

@moolen
Copy link

moolen commented Nov 27, 2015

+1
Thank you for this implementation.

@yeepom
Copy link

yeepom commented Dec 9, 2015

+1
Thank you!
I just used volley in my Android project, but it cannot save cookies.The file is really what I want!

@vctrtello1
Copy link

Thank you, works impresive

@ayratinirani
Copy link

Can you give an example app

@dhairav
Copy link

dhairav commented Jul 4, 2016

First of all, thanks a lot for all the help!, I'm a beginner and i need to save sign in throughout an app, so how do i request the cookie back from the cookie store and apply it with volley in the post sign in subsequent requests?

@mmynsted
Copy link

Where are you removing cookies from SharedPreferences? It looks like you remove cookies from the CookieStore but only from SharedPreferences when adding a new cookie.

@arvi
Copy link

arvi commented Jun 10, 2017

This also works for OKHTTP3 + Retrofit 2.

For some reason, other solutions specific to Retrofit is giving me issues with a nodejs using passportjs. The socket.handshake.session does not store passport user even if user is already logged in. I TRIED THIS AND IT WORKED! Session is persistent and can now retrieve passport object from socket session :)

        PersistentCookieStore cookieStore = new PersistentCookieStore(context);
        CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ORIGINAL_SERVER);
        CookieHandler.setDefault(cookieManager);

        return new OkHttpClient.Builder()
                .sslSocketFactory(getSslSocketFactory(caInput), getTrustManager())
                .addNetworkInterceptor(new StethoInterceptor())
                .addInterceptor(loggingInterceptor)
                .cookieJar(new JavaNetCookieJar(cookieManager))
                .build();

@mridah
Copy link

mridah commented Aug 10, 2017

@lezorich, i get a cookie when i login to a website and i need to send that cookie with each request i make. can you please post a sample code for doing the same ?

This is my current code:

    RequestQueue queue = VolleySingleton.getInstance(this.getApplicationContext()).
            getRequestQueue();

    String url = "https://my_api_url";

    JsonObjectRequest jsObjRequest = new JsonObjectRequest
            (Request.Method.POST, url, null, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    Log.i(">>>>>resp: ", "Response: " + response.toString());
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO Auto-generated method stub
                    Log.i(">>>>>resp: ", "Error: " + error.toString());
                }
            }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("aaaa", "dddd");
            return params;
        }

    };
    
    VolleySingleton.getInstance(this).addToRequestQueue(jsObjRequest);

@sandeep-END
Copy link

Volley is giving ServorError when this CookieStore is bieng used, If I remove the line to set this, Volley works file but the response returns invalid session.
Do you have any idea why this happens like this?

@harisankerPradeep
Copy link

@lezorich what happens when cookies are removed? Won't it still be stored in the persistent storage?

@ab5y
Copy link

ab5y commented Oct 9, 2018

Hey Lukas,
Thank you for this!
I am facing one issue, though. If I kill the app, and then restart it, I am being logged out. Is this the expected behaviour?
Thank you, again!

@OroshiX
Copy link

OroshiX commented Oct 29, 2018

@lezorich Hello Lukas,
I have the same problem as @ab5y: if I kill the application and restart it, I am logged out. However, if I only "quit" by pressing back, I am still logged in.
Do you have any idea why it behaves like that?
Thanks for this gist!

@asadullah06
Copy link

asadullah06 commented Nov 27, 2018

Hello, there is another easy way to maintain cookies session and that is to add this line in a class that is extended with APPLICATION class: CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

@noorsyyed
Copy link

Hello, there is another easy way to maintain cookies session and that is to add this line in a class that is extended with APPLICATION class: CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

@asadullah06 did it work for you ? so cookies are stored automatic and no need to explicitly send them in subsequent requests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment