Saltar al contenido

Uso de cookies con la biblioteca de Android Volley

Nuestros mejores investigadores han agotado sus provisiones de café, investigando diariamente por la solución, hasta que Armando encontró el resultado en GitLab y ahora la comparte con nosotros.

Solución:

En realidad, Volley no realiza solicitudes HTTP por sí mismo y, por lo tanto, no administra las cookies directamente. En su lugar, usa una instancia de HttpStack para hacer esto. Hay dos implementaciones principales:

  • HurlStack: usa HttpUrlConnection debajo del capó
  • HttpClientStack: usa Apache HttpClient bajo el capó

La gestión de cookies es responsabilidad de esos HttpStacks. Y cada uno maneja las Cookies de manera diferente.

Si necesita admitir <2.3, entonces debe usar HttpClientStack:

Configura una instancia de HttpClient y pásala a Volley para que la use debajo del capó:

// If you need to directly manipulate cookies later on, hold onto this client
// object as it gives you access to the Cookie Store
DefaultHttpClient httpclient = new DefaultHttpClient();

CookieStore cookieStore = new BasicCookieStore();
httpclient.setCookieStore( cookieStore );

HttpStack httpStack = new HttpClientStack( httpclient );
RequestQueue requestQueue = Volley.newRequestQueue( context, httpStack  );

La ventaja de esto frente a la inserción manual de cookies en los encabezados es que obtiene una administración de cookies real. Las cookies en su tienda responderán adecuadamente a los controles HTTP que expiran o actualizan.

He ido un paso más allá y he subclasificado BasicCookieStore para poder conservar automáticamente mis cookies en el disco.

¡SIN EMBARGO! Si tu no necesita ser compatible con versiones anteriores de Android. Solo usa este método:

// CookieStore is just an interface, you can implement it and do things like
// save the cookies to disk or what ever.
CookieStore cookieStore = new MyCookieStore();
CookieManager manager = new CookieManager( cookieStore, CookiePolicy.ACCEPT_ALL );
CookieHandler.setDefault( manager  );

// Optionally, you can just use the default CookieManager
CookieManager manager = new CookieManager();
CookieHandler.setDefault( manager  );

HttpURLConnection consultará el CookieManager implícitamente. HttpUrlConnection también es más eficaz y un poco más limpio para implementar y trabajar con IMO.

¡vmirinov tiene razón!

Así es como resolví el problema:

Clase de solicitud:

public class StringRequest extends com.android.volley.toolbox.StringRequest 

    private final Map _params;

    /**
     * @param method
     * @param url
     * @param params
     *            A @link HashMap to post with the request. Null is allowed
     *            and indicates no parameters will be posted along with request.
     * @param listener
     * @param errorListener
     */
    public StringRequest(int method, String url, Map params, Listener listener,
            ErrorListener errorListener) 
        super(method, url, listener, errorListener);

        _params = params;
    

    @Override
    protected Map getParams() 
        return _params;
    

    /* (non-Javadoc)
     * @see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
     */
    @Override
    protected Response parseNetworkResponse(NetworkResponse response) 
        // since we don't know which of the two underlying network vehicles
        // will Volley use, we have to handle and store session cookies manually
        MyApp.get().checkSessionCookie(response.headers);

        return super.parseNetworkResponse(response);
    

    /* (non-Javadoc)
     * @see com.android.volley.Request#getHeaders()
     */
    @Override
    public Map getHeaders() throws AuthFailureError  headers.equals(Collections.emptyMap())) 
            headers = new HashMap();
        

        MyApp.get().addSessionCookie(headers);

        return headers;
    

y MyApp:

public class MyApp extends Application 
    private static final String SET_COOKIE_KEY = "Set-Cookie";
    private static final String COOKIE_KEY = "Cookie";
    private static final String SESSION_COOKIE = "sessionid";

    private static MyApp _instance;
  private RequestQueue _requestQueue;
  private SharedPreferences _preferences;

    public static MyApp get() 
        return _instance;
    

    @Override
    public void onCreate() 
        super.onCreate();
        _instance = this;
            _preferences = PreferenceManager.getDefaultSharedPreferences(this);
        _requestQueue = Volley.newRequestQueue(this);
    

    public RequestQueue getRequestQueue() 
        return _requestQueue;
    


    /**
     * Checks the response headers for session cookie and saves it
     * if it finds it.
     * @param headers Response Headers.
     */
    public final void checkSessionCookie(Map headers) 
        if (headers.containsKey(SET_COOKIE_KEY)
                && headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) 
                String cookie = headers.get(SET_COOKIE_KEY);
                if (cookie.length() > 0) 
                    String[] splitCookie = cookie.split(";");
                    String[] splitSessionId = splitCookie[0].split("=");
                    cookie = splitSessionId[1];
                    Editor prefEditor = _preferences.edit();
                    prefEditor.putString(SESSION_COOKIE, cookie);
                    prefEditor.commit();
                
            
    

    /**
     * Adds session cookie to headers if exists.
     * @param headers
     */
    public final void addSessionCookie(Map headers) 
        String sessionId = _preferences.getString(SESSION_COOKIE, "");
        if (sessionId.length() > 0) 
            StringBuilder builder = new StringBuilder();
            builder.append(SESSION_COOKIE);
            builder.append("=");
            builder.append(sessionId);
            if (headers.containsKey(COOKIE_KEY)) 
                builder.append("; ");
                builder.append(headers.get(COOKIE_KEY));
            
            headers.put(COOKIE_KEY, builder.toString());
        
    


El código de transporte HTTP predeterminado para Volley es HttpUrlConnection. Si estoy leyendo la documentación correctamente, debe optar por el soporte automático de cookies de sesión:

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

Consulte también ¿Debería HttpURLConnection con CookieManager manejar automáticamente las cookies de sesión?

Te invitamos a añadir valor a nuestra información añadiendo tu experiencia en las ilustraciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *