Manipulação de cookies no PhoneGap / Cordova

89

Estou trabalhando em um aplicativo PhoneGap com uso de sessão do servidor. Ele precisa de cookies para lidar com a sessão. Além disso, o cookie do balanceador de carga também deve ser tratado. Portanto, não há como contornar. Como você lida com Cookies em seu aplicativo PhoneGap?

Já realizei algumas pesquisas:

  • Alguns dizem que o manuseio de cookies pode depender de o servidor não definir cookies para agentes de usuário desconhecidos (IIS): Sessão PhoneGap (cookies) no iOS
  • Em JavaScript, os cookies podem ser definidos com document.cookie = ..., mas eles não são salvos no PhoneGap e perdidos. Antes de disparar solicitações xhr, ele funciona.
  • Os cookies podem ser recuperados após a solicitação xhr com xhr.getResponseHeader ('Set-Cookie'). Mas apenas quando realmente definido no servidor. Infelizmente, o jQuery remove o cabeçalho "Cookie".
  • A propriedade JavaScript document.cookie não é atribuída e não é atualizada após solicitações (xhr).
  • Alguns sugerem que o localStorage salve ids de sessão etc. Mas todos os scripts podem acessá-lo e isso pode ser um problema de segurança XSS. Os cookies contornam esse problema usando o sinalizador httponly.
  • iOS: Existem algumas modificações que irão alterar o comportamento do webView para suportar cookies. Mas eles parecem não funcionar com iOS 6 e PhoneGap 2.5: https://groups.google.com/forum/?fromgroups=#!topic/phonegap/ZJE1nxX63ow
  • Os cookies parecem estar habilitados por padrão no AppDelegate.m (v2.5).
Bernd
fonte
O que você quer dizer com todos os scripts podem acessar localStorage? Achei que fosse separado e meio isolado para cada aplicativo PhoneGap ... não?
Jayarjo
Talvez este plugin ajude? github.com/assembly/cordova-cookie-jar
J Chris A

Respostas:

68

Amigo, também tentei sem sucesso usar cookies com phonegap. A solução foi usar localStorage.

Exemplo-chave rápido:

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

Exemplo rápido de conjunto de itens:

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

Obter Item Exemplo Rápido

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

Exemplo rápido de remoção de item:

 window.localStorage.removeItem("key");

Exemplo rápido claro:

 window.localStorage.clear();

Se você usa javascript para celular e web, pode usar este código para detectar esse ambiente:

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

Referências: 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

Esteja ciente: usar a navegação anônima no iOS pode fazer com que o armazenamento local não funcione como esperado. Um teste simples que está funcionando bem para mim:

$(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
fonte
1
Tiago, Em relação à sua resposta, poderia esclarecer se a opção localStorage persiste (não ocorre perda de dados) até a aplicação ser desinstalada? e também, podemos dizer que é certo que outros aplicativos não podem alcançar um par de valores-chave que eu defini em meu aplicativo?
shamaleyte de
2
@shamaleyte "LocalStorage atua mais como cache do que cookies, onde a persistência de cada um depende das configurações do navegador do usuário e como o próprio navegador o implementa (já que não há especificações para ele)" stackoverflow.com/questions/9948284/…
Tiago Gouvêa
NÃO use armazenamento local em Córdoba! no iOS, o processo do sistema pode liberar o armazenamento local à vontade. gonehybrid.com/…
Nico Westerdale
4

Semelhante a você, eu queria usar cookies definidos por um servidor em meu aplicativo para que meu aplicativo fosse consistente com a web e não exigisse um ID de dispositivo separado ou outro método de autenticação.

O que descobri é o seguinte:

  • Cookies definidos via AJAX (por exemplo, jQuery $.get()ou$.post() ) não persistem
  • Cookies criados em uma 'inAppBrowser' não persistem.

A maneira de fazer um cookie persistir é usar o inAppBrowser in .

Primeiro, configure um servidor simples que aceite como parâmetro GET parâmetros de valor-chave que você deseja manter. Eu sou um cara python / tornado, então meu servidor pode ser assim:

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

Então, em seu aplicativo:

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);    
    });
}

Você pode então chamar isso da seguinte maneira:

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

Você também pode anexar o id da sessão ao url solicitante e, dependendo da linguagem do aplicativo do servidor, buscar os dados da sessão usando o valor do id da sessão da string de consulta que você passou - por exemplo, em PHP, você pode abrir uma sessão existente passando o id da sessão. Embora isso não seja recomendado devido aos riscos de sequestro de sessão, você pode testar facilmente o IP e o navegador para ter certeza de que a sessão está vindo do mesmo cliente. É claro que isso exigiria que você expirasse sua sessão assim que o cliente fechasse o navegador da sessão e limitaria o armazenamento de visualizações em cache, pois a sessão seria incluída no html real. Armazenar dados no dispositivo local, pelo menos para mim, não é realmente uma opção, pois expõe muito ao cliente, o que é, na minha opinião, um risco de segurança muito maior.

código moderno
fonte
Você também pode enviá-lo por meio de um post XmtHttpRequest, como usar $.post()em jQuery, e definir uma variável local. Se você criptografar tudo, isso é bastante seguro.
JVE999 de
@ JVE999 como criptografar cookies que são salvos por padrão na visualização da web?
LoveForDroid
3

Use device_idpara endereçar certos registros no lado do servidor. Criar uma tabela de banco de dados chamado sessionno seu servidor com device_id, cookiename, cookievalueetimestamp como colunas.

Quando um cliente acessa seu servidor web via app phonegap, pegue o dele device_ide guarde os cookies em sua mesa. odevice_id here atua como o token de acesso no protocolo OAuth.

Agora, por razões de segurança, você precisa reduzir o período de validade desses registros, porque o device_id é permanente e seu cliente gostaria de vender seus telefones um dia. Portanto, use timestamppara armazenar o último acesso do cliente e excluir o registro se ele não tiver sido acessado por, digamos, 10 dias.

Abdullah Al-Salloum
fonte
3

Estou usando o Cordova 6.1 (versão mais recente no momento) e, na verdade, encontrei o seguinte:

Se eu definir o cookie via Javascript usando document.cookie = ... então ele não funciona. No entanto, se eu enviar uma função setCookie via Ajax para o servidor com uma função 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=/"; 
    }
} 

e definir o cookie no lado do servidor usando

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

então realmente funciona!

Espero que isto ajude. Felicidades

SF
fonte
0

Tive o mesmo problema e decidi mover evrth para localStorage. Eu escrevi o plugin para que você também possa usá-lo: angular-cookies-mirror

uamanager
fonte
0

claro que você pode.

app iônico basta enviar um requset ajax, cookie funciona bem ou não depende do servidor.

eu tenho trabalho com servidor Django python e servidor de nó, ambos os cookies funcionaram muito bem

código do nó abaixo

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();
});

api resto

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 aplicativo iônico

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)
  });
}

você pode verificar meu código de curso aqui

Wangjinyang
fonte
0

Acho que a questão é fundamentalmente sobre como definir cookies do lado do cliente para um aplicativo Cordova. A maioria das informações sobre este tópico implica que a configuração de cookies do lado do cliente não funciona para Cordova.

Mas eu encontrei um plugin que me permite definir cookies do lado do cliente para meu aplicativo Cordova.

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

Simplesmente funciona!

BruceJo
fonte
0

Eu também tive problemas de cookie de sessão com solicitações Cordova + XHR. Os cookies são perdidos a cada reinicialização do aplicativo. Duas coisas resolveram meus problemas:

  1. Os cookies devem ter uma data de validade.

  2. Todas as solicitações XHR devem ter o sinalizador withCredentials definido como verdadeiro.

Moe
fonte