Manejo de cookies en PhoneGap / Cordova

88

Estoy trabajando en una aplicación PhoneGap con uso de sesión de servidor. Necesita cookies para manejar la sesión. Además, la cookie del equilibrador de carga también debe manejarse. Entonces no hay forma de evitarlo. ¿Cómo maneja las cookies en su aplicación PhoneGap?

Ya he realizado algunas investigaciones:

  • Algunos dicen que el manejo de cookies puede depender de que el servidor no establezca cookies para agentes de usuario desconocidos (IIS): Sesión PhoneGap (cookies) en iOS
  • En JavaScript, las cookies se pueden configurar con document.cookie = ..., pero no se guardan en PhoneGap y se pierden. Antes de disparar las solicitudes xhr, funciona.
  • Las cookies se pueden recuperar después de la solicitud xhr con xhr.getResponseHeader ('Set-Cookie'). Pero solo cuando está realmente configurado en el servidor. Desafortunadamente, jQuery elimina el encabezado "Cookie".
  • La propiedad document.cookie de JavaScript no se asigna y no se actualiza después de las solicitudes (xhr).
  • Algunos sugieren localStorage para guardar los identificadores de sesión, etc. Pero todos los scripts pueden acceder a él y esto podría ser un problema de seguridad XSS. Las cookies solucionan este problema mediante el uso de la marca httponly.
  • iOS: hay algunas modificaciones que cambiarán el comportamiento de webView para admitir cookies. Pero parece que no funcionan con iOS 6 y PhoneGap 2.5: https://groups.google.com/forum/?fromgroups=#!topic/phonegap/ZJE1nxX63ow
  • Las cookies parecen estar habilitadas de forma predeterminada en AppDelegate.m (v2.5).
Bernd
fuente
¿Qué quiere decir que todos los scripts pueden acceder a localStorage? Pensé que estaba separado y un poco protegido para cada aplicación PhoneGap ... ¿no?
jayarjo
¿Quizás este complemento ayude? github.com/assembly/cordova-cookie-jar
J Chris A

Respuestas:

68

Amigo, también he intentado sin éxito usar cookies con phonegap. La solución fue usar localStorage.

Ejemplo rápido clave:

 var keyName = window.localStorage.key(0);

Ejemplo rápido de artículo de conjunto:

 window.localStorage.setItem("key", "value");

Ejemplo rápido de obtener artículo

 var value = window.localStorage.getItem("key");
 // value is now equal to "value"

Ejemplo rápido de quitar artículo:

 window.localStorage.removeItem("key");

Ejemplo rápido claro:

 window.localStorage.clear();

Si usa su javascript tanto para dispositivos móviles como para la web, puede usar este código para detectar ese entorno:

var wl = window.location.href;
var mob = (wl.indexOf("android")>0);

Referencias: http://docs.phonegap.com/en/1.2.0/phonegap_storage_storage.md.html#localStorage http://cordova.apache.org/docs/en/6.x/cordova/storage/storage.html # page-toc-source

Tenga en cuenta: el uso de la navegación anónima en iOS puede hacer que el almacenamiento local no funcione como se esperaba. Una prueba simple que me está funcionando bien:

$(document).ready(function () {
    try {
        localStorage.setItem('test', '1');
    } catch (Err) {
        if (Err.message.indexOf('QuotaExceededError') > -1) {
            // Tell the user they are in anonymous mode
            // Sugest it to go to https://support.apple.com/pt-br/HT203036 to get help to disable it
            }
        }
    }
});
Tiago Gouvêa
fuente
1
Tiago, Con respecto a su respuesta, ¿podría aclarar si la opción localStorage persiste (no se pierden datos) hasta que se desinstala la aplicación? y también, ¿podemos decir que es seguro que otras aplicaciones no pueden alcanzar un par clave-valor que configuré en mi aplicación?
shamaleyte
2
@shamaleyte "LocalStorage actúa más como caché que como cookies, donde la persistencia de cada uno depende de la configuración del navegador del usuario y de cómo el navegador mismo lo implementa (ya que no hay especificaciones para ello)" stackoverflow.com/questions/9948284/…
Tiago Gouvêa
¡NO use almacenamiento local en Córdoba! en iOS, el proceso del sistema puede vaciar el almacenamiento local a voluntad. wenthybrid.com/…
Nico Westerdale
4

De manera similar a usted, quería usar cookies establecidas por un servidor dentro de mi aplicación para que mi aplicación fuera coherente con la web y no requiriera una identificación de dispositivo separada u otro método de autenticación.

Lo que descubrí es lo siguiente:

  • Las cookies establecidas a través de AJAX (por ejemplo, jQuery $.get()o $.post()) no persisten
  • Cookies creadas en un 'inAppBrowser' no persisten.

La forma de conseguir que una cookie persista es utilizando el complemento inAppBrowser .

Primero, configure un servidor simple que acepte como parámetro GET los parámetros clave-valor que desea conservar. Soy un tipo de python / tornado, por lo que mi servidor podría verse así:

class PersistCookieHandler(tornado.web.RequestHandler):
   @tornado.gen.coroutine
   def get(self):
      token = self.get_argument('token')
      self.set_secure_cookie('token',token)

Luego, en tu aplicación:

function persistToken(token,success_cb, error_cb) {
    // replace with your URL
    url = 'SECURE_SERVER_URL_THAT_HANDLES_SET_COOKIE';  

    // _blank tells inAppBrowser to load in background (e.g., invisible)
    var ref = window.open(url, '_blank', 'location=no,toolbar=no');

    // attach a listener to the window which closes it when complete
    ref.addEventListener('loadstop', function(event) { 
        ref.close();
        success_cb();  // call our success callback
    });

    // attach a listener for server errors 
    ref.addEventListener('loaderror', function(event) { 
        // call our error callback
        error_cb(event);    
    });
}

A continuación, puede llamar a esto de la siguiente manera:

persistToken(
   someToken,
   function() {
       console.log("token persisted");
   },
   function() {
       console.log("something went wrong);
   }
);
Mike N
fuente
3

También puede agregar la identificación de la sesión a la URL solicitante y, según el idioma de la aplicación del servidor, recuperar los datos de la sesión utilizando el valor de la identificación de la sesión de la cadena de consulta que pasó. Si bien esto no se recomienda debido a los riesgos de secuestro de sesión, puede probar fácilmente la IP y el navegador para asegurarse de que la sesión provenga del mismo cliente. Por supuesto, esto requeriría que expirara su sesión tan pronto como el cliente cierre el navegador de sesiones y limitaría el almacenamiento en caché de las vistas ya que la sesión se incluiría en el html real. Almacenar datos en el dispositivo local para mí al menos no es realmente una opción, ya que expone demasiado al cliente, lo que en mi opinión es un riesgo de seguridad mucho mayor.

moderncode
fuente
También puede enviarlo a través de una publicación XmtHttpRequest, como usar $.post()en jQuery, luego establecer una variable local. Si encripta todo, es bastante seguro.
JVE999
@ JVE999 ¿cómo cifrar las cookies que se guardan de forma predeterminada en la vista web?
LoveForDroid
3

Utilice device_idpara abordar ciertos registros en el lado del servidor. Crear una tabla de base de datos llamada sessionen su servidor con device_id, cookiename, cookievaluey timestampcomo columnas.

Cuando un cliente accede a su servidor web a través de la aplicación phonegap, obtenga el suyo device_idy almacene las cookies en su mesa. El device_id hereactúa como el token de acceso en el protocolo OAuth.

Ahora, por razones de seguridad, debe reducir el período de validez de esos registros, porque el device_id es permanente y su cliente querría vender sus teléfonos algún día. Por lo tanto, utilice timestamppara almacenar el último acceso del cliente y elimine el registro si no se ha accedido durante, digamos, 10 días.

Abdullah Al-Salloum
fuente
3

Estoy usando Cordova 6.1 (la versión más reciente en este momento) y, de hecho, encontré lo siguiente:

Si configuro la cookie a través de Javascript usando document.cookie = ... entonces no funciona. Sin embargo, si envío una función setCookie a través de Ajax al servidor con una función como

function setCookie(name, value, exdays) {

    if(isPhonegap() === true){
        var data = "typ=function&functionType=setCookie&name="+name+"&value="+value+"&exdays="+exdays;
        loadAjax(data, false);    
    }
    else if (!(document.cookie.indexOf("name") >= 0)){
            var expires;
            if (exdays) {
                var date = new Date();
                date.setTime(date.getTime()+(exdays*24*60*60*1000));
                expires = "; expires="+date.toGMTString();
            }
            else{
                expires = "";
            }
            document.cookie = name+"="+value+expires+"; path=/"; 
    }
} 

y configure la cookie en el lado del servidor usando

setcookie($cookie, $value, $expires , "/" );

entonces realmente funciona!

Espero que esto ayude. Salud

SF
fuente
0

Tuve el mismo problema y decidí mover evrth a localStorage. Escribí el complemento para que puedas usarlo también: angular-cookies-mirror

uamanager
fuente
0

por supuesto que puede.

La aplicación iónica solo envía un requset ajax, las cookies funcionan bien o no dependen del servidor.

Tengo trabajo con el servidor Python Django y el servidor de nodo, ambas cookies funcionaron muy bien

código de nodo a continuación

app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("Access-Control-Allow-Credentials",true);
next();
});

resto api

router.get('/setCookies', function(req, res, next) {
var now = new Date();
var nextYear=new Date(now.setFullYear(now.getFullYear()+1));
//you can change the cookie key and value by your self here
res.cookie('cookiesTest', 'set cookies success,your cookies can be set by server', { expires: nextYear, httpOnly: true });
res.status(200)
res.end('SET COOKIES SUCCESS')
});

router.get('/getCookies', function(req, res, next) {
res.status(200)
res.end(JSON.stringify(req.cookies))
});

código de aplicación iónica

var server='http://[YOUR IP HERE]:3000'

$scope.setCookies=function() {
  $http({
    url: server + '/setCookies',
    method: 'GET'
  }).success(function (data, header, config, status) {
    alert('set cookies success,look console')
    $scope.setCookiesStatu=false
    console.log(data)
    $scope.cookiesValue=data
  }).error(function (data, header, config, status) {
    alert('set cookies error,check console or your server address is wrong')
    console.log(data)
  });
}

$scope.getCookies=function() {
  $http({
    url: server + '/getCookies',
    method: 'GET'
  }).success(function (data, header, config, status) {
    alert('get cookies success,look console')
    console.log(data)
    $scope.cookiesValue=data
  }).error(function (data, header, config, status) {
    alert('get cookies error,check console or your server address is wrong')
    console.log(data)
  });
}

puedes consultar mi código de fuente aquí

Wangjinyang
fuente
0

Creo que la pregunta es fundamentalmente sobre la configuración de cookies del lado del cliente para una aplicación cordova. La mayor parte de la información sobre este tema implica que la configuración de cookies del lado del cliente no funciona para cordova.

Pero encontré un complemento que me permite configurar cookies del lado del cliente para mi aplicación cordova.

Consulte https://www.npmjs.com/package/cordova-plugin-cartegraph-cookie-master .

¡Simplemente funciona!

BruceJo
fuente
0

También tuve problemas con las cookies de sesión con las solicitudes Cordova + XHR. Las cookies se pierden cada vez que se reinicia la aplicación. Dos cosas han resuelto mis problemas:

  1. Las cookies deben tener una fecha de vencimiento.

  2. Todas las solicitudes XHR deben tener el indicador withCredentials establecido en verdadero.

Moe
fuente