在PhoneGap / Cordova中处理Cookie


88

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

我已经完成了一些研究:

  • 有人说cookie处理可能取决于服务器未为未知用户代理(IIS)设置cookie:iOS上的PhoneGap会话(cookie)
  • 在JavaScript中,可以使用document.cookie = ...设置cookie,但不会将它们保存在PhoneGap中并丢失。在触发xhr请求之前,它可以工作。
  • 可以在xhr请求后使用xhr.getResponseHeader('Set-Cookie')检索Cookie。但仅当实际在服务器上设置时。不幸的是,jQuery剥离了“ Cookie”标头。
  • 在(xhr)请求后,未分配JavaScript document.cookie属性,也未对其进行更新。
  • 一些建议使用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。

您的意思是所有脚本都可以访问localStorage?我以为它是单独的,并且对于每个PhoneGap应用都有点沙盒……不是吗?
jayarjo 2014年


也许这个插件有帮助?github.com/assembly/cordova-cookie-jar
J Chris

Answers:


68

朋友,我也尝试过不成功将cookie与phonegap一起使用。解决方案是使用localStorage。

关键快速示例:

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

设置项目快速示例:

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

获取项目快速示例

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

删除项目快速示例:

 window.localStorage.removeItem("key");

清除快速示例:

 window.localStorage.clear();

如果您在移动设备和网络上都使用javascript,则可以使用以下代码检测该环境:

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

参考: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

请注意:在iOS上使用匿名导航可能会使本地存储无法正常运行。一个对我来说很好的简单测试:

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

1
Tiago,关于您的回答,能否请您说明在卸载应用程序之前localStorage选项是否仍然存在(不会丢失数据)?而且,我们是否可以肯定地说其他应用程序不能达到我在我的应用程序中设置的键值对?
shamaleyte

2
@shamaleyte“ LocalStorage的行为更像是缓存而不是cookie,每个持久性的持久性取决于用户的浏览器设置以及浏览器本身如何实现(因为没有规范),” stackoverflow.com/questions/9948284/…
TiagoGouvêa2015年

请不要在科尔多瓦使用本地存储!在iOS中,系统进程可以随意刷新本地存储。gonehybrid.com/...
尼科Westerdale

4

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

我发现以下内容:

  • 通过AJAX设置的Cookie(例如jQuery$.get()$.post())不会持续存在
  • 在“ 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);
   }
);

3

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


您也可以通过发布XmtHttpRequest来发送它,例如$.post()在jQuery中使用,然后设置一个局部变量。如果您加密所有内容,那将非常安全。
JVE999 2014年

@ JVE999如何加密Web视图默认保存的cookie?
LoveForDroid

3

使用device_id来解决服务器端的某些记录。创建一个名为数据库表session与您的服务器上device_idcookienamecookievaluetimestamp为列。

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

现在出于安全原因,您需要减少这些记录的有效期,因为device_id是永久性的,并且您的客户希望有一天出售其电话。因此,用于timestamp存储客户端的最后一次访问,如果该记录在10天内没有被访问,则将其删除。


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 , "/" );

那么它确实有效!

希望这可以帮助。干杯



0

当然可以。

ionic应用程序仅发送ajax requset,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)
  });
}

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



0

我也有Cordova + XHR请求的会话cookie问题。每次重新启动应用程序时,cookie都会丢失。两件事解决了我的问题:

  1. Cookies必须具有有效期限。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.