Obsługa plików cookie w PhoneGap / Cordova

88

Pracuję nad aplikacją PhoneGap z wykorzystaniem sesji serwera. Do obsługi sesji potrzebuje plików cookie. Dodatkowo należy obsłużyć ciasteczko z load balancera. Więc nie ma innego wyjścia. Jak postępujesz z plikami cookie w aplikacji PhoneGap?

Przeprowadziłem już pewne badania:

  • Niektórzy twierdzą, że obsługa plików cookie może zależeć od tego, czy serwer nie ustawia plików cookie dla nieznanych agentów użytkownika (IIS): sesja PhoneGap (pliki cookie) w systemie iOS
  • W JavaScript pliki cookie można ustawić za pomocą document.cookie = ..., ale nie są one zapisywane w PhoneGap i tracone. Przed odpaleniem xhr żąda to działa.
  • Pliki cookie można pobrać po żądaniu xhr za pomocą xhr.getResponseHeader ('Set-Cookie'). Ale tylko wtedy, gdy faktycznie jest ustawiony na serwerze. Niestety, jQuery usuwa nagłówek „Cookie”.
  • Właściwość JavaScript document.cookie nie jest przypisywana i nie jest aktualizowana po żądaniach (xhr).
  • Niektórzy sugerują, że localStorage zapisuje identyfikatory sesji itp. Ale wszystkie skrypty mają do niego dostęp i może to być problem z bezpieczeństwem XSS. Pliki cookie pozwalają obejść ten problem, używając flagi httponly.
  • iOS: Istnieją pewne modyfikacje, które zmienią zachowanie WebView w celu obsługi plików cookie. Ale wydaje się, że nie działają z iOS 6 i PhoneGap 2.5: https://groups.google.com/forum/?fromgroups=#!topic/phonegap/ZJE1nxX63ow
  • Wydaje się, że pliki cookie są domyślnie włączone w AppDelegate.m (v2.5).
Bernd
źródło
Co masz na myśli, że wszystkie skrypty mają dostęp do localStorage? Myślałem, że to osobne i trochę piaskownicy dla każdej aplikacji PhoneGap ... nie?
jayarjo
Może ta wtyczka pomaga? github.com/assembly/cordova-cookie-jar
J Chris A

Odpowiedzi:

68

Przyjacielu, też bez powodzenia próbowałem używać plików cookie z phonegap. Rozwiązaniem było użycie localStorage.

Kluczowy szybki przykład:

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

Szybki przykład zestawu pozycji:

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

Szybki przykład pobierania przedmiotu

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

Szybki przykład usuwania pozycji:

 window.localStorage.removeItem("key");

Wyczyść szybki przykład:

 window.localStorage.clear();

Jeśli używasz javascript zarówno dla telefonów komórkowych, jak i stron internetowych, możesz użyć tego kodu, aby wykryć to środowisko:

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

Źródła: 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

Uwaga: korzystanie z anonimowej nawigacji na iOS może spowodować, że lokalny magazyn nie będzie działał tak, jak spodziewano się. Prosty test, który dla mnie działa dobrze:

$(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
źródło
1
Tiago, jeśli chodzi o Twoją odpowiedź, czy mógłbyś wyjaśnić, czy opcja localStorage utrzymuje się (nie dochodzi do utraty danych), dopóki aplikacja nie zostanie odinstalowana? a także, czy możemy powiedzieć, że na pewno inne aplikacje nie mogą osiągnąć pary klucz-wartość, którą ustawiłem w mojej aplikacji?
shamaleyte
2
@shamaleyte „LocalStorage działa bardziej jak pamięć podręczna niż pliki cookie, gdzie trwałość każdego z nich zależy od ustawień przeglądarki użytkownika i sposobu, w jaki sama przeglądarka je implementuje (ponieważ nie ma dla niego specyfikacji)” stackoverflow.com/questions/9948284/ ...
Tiago Gouvêa
Proszę NIE korzystać z lokalnego magazynu w Kordowie! w iOS proces systemowy może dowolnie opróżniać pamięć lokalną. gonehybrid.com/…
Nico Westerdale
4

Podobnie jak Ty, chciałem używać plików cookie ustawionych przez serwer w mojej aplikacji, aby moja aplikacja była spójna z siecią i nie wymagała oddzielnego identyfikatora urządzenia ani innej metody uwierzytelniania.

Oto co odkryłem:

  • Pliki cookie ustawione przez AJAX (np. JQuery $.get()lub $.post()) nie są trwałe
  • Cookies ustawione w „inAppBrowser” nie ustępują.

Sposobem na utrwalenie pliku cookie jest użycie wtyczki inAppBrowser .

Najpierw skonfiguruj prosty serwer, który akceptuje jako parametr GET parametry klucz-wartość, które chcesz zachować. Jestem facetem od Pythona / Tornado, więc mój serwer może wyglądać tak:

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

Następnie w swojej aplikacji:

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

Możesz to nazwać w następujący sposób:

persistToken(
   someToken,
   function() {
       console.log("token persisted");
   },
   function() {
       console.log("something went wrong);
   }
);
Mike N
źródło
3

Możesz również dołączyć identyfikator sesji do adresu URL żądającego i, w zależności od języka aplikacji serwera, pobrać dane sesji przy użyciu wartości identyfikatora sesji, którą podałeś - na przykład w PHP można otworzyć istniejącą sesję, przekazując identyfikator sesji. Chociaż nie jest to zalecane ze względu na ryzyko przechwytywania sesji, można łatwo przetestować adres IP i przeglądarkę, aby upewnić się, że sesja pochodzi z tego samego klienta. Wymagałoby to oczywiście wygaśnięcia sesji, gdy tylko klient zamknie przeglądarkę sesji i ograniczyłoby buforowanie widoków, ponieważ sesja byłaby uwzględniona w faktycznym html. Przechowywanie danych na lokalnym urządzeniu przynajmniej dla mnie nie jest tak naprawdę opcją, ponieważ naraża klienta zbyt wiele, co moim zdaniem jest znacznie większym zagrożeniem dla bezpieczeństwa.

moderncode
źródło
Możesz również wysłać go za pośrednictwem XmtHttpRequest pocztowego, takiego jak użycie $.post()w jQuery, a następnie ustawić zmienną lokalną. Jeśli szyfrujesz wszystko, jest to całkiem bezpieczne.
JVE999
@ JVE999 jak zaszyfrować pliki cookie, które są domyślnie zapisywane przez przeglądarkę internetową?
LoveForDroid
3

Użyj, device_idaby zaadresować określone rekordy po stronie serwera. Tworzenie tabeli bazy danych o nazwie sessionna serwerze z device_id, cookiename, cookievaluei timestampjako kolumny.

Gdy klient uzyskuje dostęp do serwera WWW za pośrednictwem aplikacji phonegap, pobierz jego device_idi zapisz pliki cookie w tabeli. device_id hereDziała jako token dostępu do protokołu OAuth.

Teraz ze względów bezpieczeństwa musisz skrócić okres ważności tych rekordów, ponieważ device_id jest stały, a Twój klient chciałby pewnego dnia sprzedać swoje telefony. Dlatego użyj, timestampaby zapisać ostatni dostęp klienta i usunąć rekord, jeśli nie był używany przez, powiedzmy, 10 dni.

Abdullah Al-Salloum
źródło
3

Używam Cordova 6.1 (w tej chwili najnowsza wersja) i tak naprawdę znalazłem:

Jeśli ustawię plik cookie przez Javascript za pomocą document.cookie = ..., to nie zadziała. Jeśli jednak wyślę funkcję setCookie przez Ajax do serwera z funkcją taką jak

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=/"; 
    }
} 

i ustaw plik cookie po stronie serwera za pomocą

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

to faktycznie działa!

Mam nadzieję że to pomoże. Twoje zdrowie

SF
źródło
0

Miałem ten sam problem i postanowiłem przenieść evrth na localStorage Napisałem wtyczkę, abyś mógł z niej również korzystać: angular-cookies-mirror

uamanager
źródło
0

oczywiście, że możesz.

Aplikacja ionic wystarczy wysłać requset Ajax, plik cookie działa dobrze lub nie zależy od serwera.

Pracuję z serwerem Python Django i serwerem węzłów, oba pliki cookie działały bardzo dobrze

kod węzła poniżej

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

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

kod aplikacji ionic

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

tutaj możesz sprawdzić mój kod źródłowy

wangjinyang
źródło
0

Myślę, że zasadniczo chodzi o ustawienie plików cookie po stronie klienta dla aplikacji Cordova. Większość informacji na ten temat sugeruje, że ustawienie plików cookie po stronie klienta nie działa w przypadku Cordova.

Ale znalazłem wtyczkę, która pozwala mi ustawić pliki cookie po stronie klienta dla mojej aplikacji Cordova.

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

Po prostu działa!

BruceJo
źródło
0

Miałem również problemy z plikami cookie sesji z żądaniami Cordova + XHR. Pliki cookie są tracone przy każdym ponownym uruchomieniu aplikacji. Dwie rzeczy rozwiązały moje problemy:

  1. Pliki cookie muszą mieć datę ważności.

  2. Wszystkie żądania XHR muszą mieć flagę withCredentials ustawioną na wartość true.

Moe
źródło