在 PhoneGap/Cordova 中处理 cookie

Posted

技术标签:

【中文标题】在 PhoneGap/Cordova 中处理 cookie【英文标题】:Handling cookies in PhoneGap/Cordova 【发布时间】:2013-02-27 06:11:57 【问题描述】:

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

我已经完成了一些研究:

有人说 cookie 处理可能取决于服务器没有为未知用户代理 (IIS) 设置 cookie:PhoneGap session (cookies) on iosjavascript 中可以使用 document.cookie = ... 设置 cookie,但它们不会保存在 PhoneGap 中并且会丢失。在触发 xhr 请求之前,它可以工作。 可以在使用 xhr.getResponseHeader('Set-Cookie') 进行 xhr 请求后检索 Cookie。但只有在服务器上实际设置时。不幸的是,jQuery 去掉了“Cookie”标头。 JavaScript document.cookie 属性在 (xhr) 请求后未分配且未更新。 有些人建议使用 localStorage 来保存会话 ID 等。但是所有脚本都可以访问它,这可能是 XSS 安全问题。 Cookie 使用 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 应用程序都是独立的并且有点沙盒......不是吗? 这里:***.com/questions/15184567/… 也许这个插件有帮助? github.com/assembly/cordova-cookie-jar 【参考方案1】:

朋友,我也尝试过使用带有 phonegap 的 cookie,但没有成功。解决方案是使用 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
            
        
    
);

【讨论】:

Tiago,关于您的回答,能否请您澄清 localStorage 选项是否仍然存在(没有数据丢失发生)直到应用程序被卸载?另外,我们可以说其他应用程序无法访问我在我的应用程序中设置的键值对吗? @shamaleyte "LocalStorage 更像缓存而不是 cookie,其中每个的持久性取决于用户的浏览器设置,以及浏览器本身如何实现它(因为没有规范)" @ 987654323@ 请不要在科尔多瓦使用本地存储!在 iOS 中,系统进程可以随意刷新本地存储。 gonehybrid.com/…【参考方案2】:

与您类似,我想在我的应用程序中使用由服务器设置的 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】:

使用device_id 来处理服务器端的某些记录。在您的服务器上创建一个名为session 的数据库表,其中device_idcookienamecookievaluetimestamp 作为列。

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

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

【讨论】:

【参考方案4】:

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

【讨论】:

也可以通过post XmtHttpRequest发送,比如在jQuery中使用$.post(),然后设置一个局部变量。如果您对所有内容进行加密,那将非常安全。 @JVE999 web view默认保存的cookie如何加密?【参考方案5】:

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

如果我通过 Javascript 使用 document.cookie = ... 设置 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 , "/" );

那么它确实有效!

希望这会有所帮助。 干杯

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

当然可以。

ionic 应用只发送一个 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();
);

休息接口

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

you can check my sourse code here

【讨论】:

【参考方案8】:

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

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

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

它只是工作!

【讨论】:

【参考方案9】:

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

    Cookie 必须有过期日期。

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

【讨论】:

以上是关于在 PhoneGap/Cordova 中处理 cookie的主要内容,如果未能解决你的问题,请参考以下文章

是否支持在 phonegap (cordova) 中使用声音捕获视频?

在 PhoneGap/Cordova 1.5.0 中显示启动画面

如何在推送插件 PhoneGap/Cordova 4.0 中替换 window.plugin(已弃用)?

Angular工厂中的Phonegap / Cordova功能

IOS/android + phonegap/cordova框架中的返回键

PhoneGap / Cordova 回调错误 - 在 PhoneGap 中未执行 RestKit 完成功能