94

我正在开发一个使用服务器会话的 PhoneGap 应用程序。它需要 cookie 来处理会话。此外,还应处理来自负载平衡器的 cookie。所以没有办法。您如何处理 PhoneGap 应用程序中的 Cookie?

我已经完成了一些研究:

  • 有人说 cookie 处理可能取决于服务器没有为未知用户代理 (IIS) 设置 cookie:iOS 上的 PhoneGap session (cookies)
  • 在 JavaScript 中,cookie 可以使用 document.cookie = ... 设置,但它们不会保存在 PhoneGap 中并且会丢失。在触发 xhr 请求之前,它可以工作。
  • 可以在使用 xhr.getResponseHeader('Set-Cookie') 进行 xhr 请求后检索 Cookie。但只有在服务器上实际设置时。不幸的是,jQuery 去掉了“Cookie”标头。
  • JavaScript document.cookie 属性在 (xhr) 请求之后未分配且未更新。
  • 有些人建议使用 localStorage 来保存会话 ID 等。但是所有脚本都可以访问它,这可能是 XSS 安全问题。Cookies 通过使用 httponly 标志来解决这个问题。
  • iOS:有一些修改会改变 webView 行为以支持 cookie。但它们似乎不适用于 iOS 6 和 PhoneGap 2.5:https ://groups.google.com/forum/?fromgroups=#!topic/phonegap/ZJE1nxX63ow
  • AppDelegate.m (v2.5) 中似乎默认启用了 Cookie。
4

9 回答 9

69

Friend, I've tried too without success to use cookies with phonegap. The solution was use localStorage.

Key Quick Example:

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

Set Item Quick Example:

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

Get Item Quick Example

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

Remove Item Quick Example:

 window.localStorage.removeItem("key");

Clear Quick Example:

 window.localStorage.clear();

If you use you javascript for both mobile and web, you can use this code to detect that enviroment:

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

References: 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

Be aware: using anonymous navigation on iOS may make localstorage not work like spected. A simple test that are working fine to me:

$(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
            }
        }
    }
});
于 2013-05-15T12:23:42.190 回答
6

与您类似,我想在我的应用程序中使用服务器设置的 cookie,以便我的应用程序与网络保持一致,并且不需要单独的设备 ID 或其他身份验证方法。

我发现如下:

  • 通过 AJAX(例如 jQuery$.get()$.post())设置的 Cookie 不会持续存在
  • 在“inAppBrowser”中设置的 Cookie确实存在。

因此让 cookie 持久化的方法是使用inAppBrowser插件。

首先,设置一个简单的服务器,它接受您想要持久化的 GET 参数键值参数。我是 python/tornado 人,所以我的服务器可能如下所示:

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

然后,在您的应用中:

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

然后,您可以按如下方式调用它:

persistToken(
   someToken,
   function() {
       console.log("token persisted");
   },
   function() {
       console.log("something went wrong);
   }
);
于 2015-12-07T10:53:54.123 回答
4

使用device_id来处理服务器端的某些记录。session在您的服务器上创建一个以device_idcookiename和为列cookievalue的数据库表。timestamp

当客户端通过 phonegap 应用程序访问您的 Web 服务器时,获取他的device_id并将 cookie 存储在您的表中。device_id here充当 OAuth 协议中的访问令牌。

现在出于安全原因,您需要缩短这些记录的有效期,因为 device_id 是永久性的,您的客户希望有一天能卖掉他们的手机。因此,用于timestamp存储客户端的最后一次访问,如果有 10 天没有访问,则删除该记录。

于 2014-08-24T16:55:38.270 回答
3

您还可以将会话 id 附加到请求 url,并根据服务器应用程序语言,使用您传递的查询字符串会话 id 值获取会话数据 - 例如在 PHP 中,您可以通过传入会话 id 打开现有会话。虽然由于会话劫持的风险不建议这样做,但您可以轻松测试 IP 和浏览器以确保会话来自同一客户端。这当然需要您在客户端关闭会话浏览器后立即使会话过期,并且会限制您缓存视图,因为会话将包含在实际的 html 中。至少对我来说,在本地设备上存储数据并不是一个真正的选择,因为它向客户端暴露了太多,在我看来这是一个更大的安全风险。

于 2013-06-06T11:28:14.457 回答
3

我正在使用 Cordova 6.1(目前最新版本),实际上我发现了以下内容:

如果我使用 document.cookie = ... 通过 Javascript 设置 cookie,那么它不起作用。但是,如果我通过 Ajax 将函数 setCookie 发送到具有类似功能的服务器

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

并使用在服务器端设置cookie

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

那么它确实有效!

希望这可以帮助。干杯

于 2016-03-31T13:26:59.807 回答
0

我认为问题基本上是关于为科尔多瓦应用程序设置客户端cookie。有关此主题的大多数信息都暗示设置客户端 cookie 不适用于 cordova。

但是我找到了一个插件,可以让我为我的科尔多瓦应用程序设置客户端 cookie。

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

它只是工作!

于 2019-04-14T18:38:06.710 回答
0

我还遇到了 Cordova + XHR 请求的会话 cookie 问题。每次应用重启时 cookie 都会丢失。有两件事解决了我的问题:

  1. Cookie 必须有一个过期日期。

  2. 所有 XHR 请求都必须将withCredentials标志设置为 true。

于 2019-07-15T14:45:25.380 回答
0

当然可以。

离子应用程序只是发送一个 ajax 请求,cookie 工作好或不依赖于服务器。

我使用过 python Django 服务器和节点服务器,两个 cookie 都运行得很好

下面的节点代码

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

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

离子应用程序代码

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

你可以在这里查看我的源代码

于 2017-08-24T07:52:25.677 回答
0

有同样的问题,并决定将 evrth 移动到 localStorage 我写了插件,所以你也可以使用它:angular-cookies-mirror

于 2017-01-08T02:05:04.170 回答