在 PhoneGap/科尔多瓦处理 cookie

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

我已经完成了一些研究:

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

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

You can also append the session id to the requesting url and depending on the server application language, fetch session data using the query string session id value you passed - example in PHP you can open an existing session by passing in the session id. While this is not recommended due to risks of session hijacking you can easily test for the IP and Browser to make sure the session is coming from the same client. This would of course require you expire your session as soon as the client closes the session browser and would limit you from caching views since the session would be included in the actual html. Storing data on the local device for me at least is not really an option as it exposes too much to the client which is in my opinion a far greater security risk.

Use the device_id to address certain records on server side. Create a database table named session on your server with device_id, cookiename, cookievalue and timestamp as columns.

When a client accesses your web server via phonegap app, get his device_id and store the cookies in your table. The device_id here acts as the access token in OAuth protocol.

Now for security reasons you need to reduce the validity period of those records, because the device_id is permenant and your client would want to sell their phones one day. Therefore, use timestamp to store the last access by the client, and delete the record if it has not been accessed for, say 10 days.

Similar to you I wanted to use cookies set by a server within my application so that my app would be consistent with the web and not require a separate device-ID or other method for authentication.

What I discovered is the following:

  • Cookies set via AJAX (e.g. jQuery $.get() or $.post()) do not persist
  • Cookies set in an 'inAppBrowser' do persist.

The way to thus get a cookie to persist is to use the inAppBrowser plugin.

First, setup a simple server that accepts as GET parameter key-value parameters you want to persist. I'm a python/tornado guy, so my server might look like:

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

Then, in your app:

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

You can then call this as follows:

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

I am using Cordova 6.1 (newest version at the moment) and actually I found the following:

If I set the cookie via Javascript using document.cookie = ... then it does not work. However if I send a function setCookie via Ajax to the server with a function like

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

and set the cookie on the server side using

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

then it does actually work!

Hope this helps. Cheers

Had the same problem, and decided to move evrth to localStorage I wrote plugin so you can use it also: angular-cookies-mirror

of course You can.

ionic app just send a ajax requset,cookie work good or not depend on server.

i have work with python Django server and node server,both cookie worked very well

node code below

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

ionic app code

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

I think the question is fundamentally about setting client side cookies for a cordova app. Most information on this topic implies that setting client side cookies does not work for cordova.

But I found a plugin that allows me to set client side cookies for my cordova app.

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

It just works!

I also had session cookie issues with Cordova + XHR requests. The cookies are lost on every app restart. Two things have solved my issues:

  1. Cookies must have an expiration date.

  2. All XHR requests must have withCredentials flag set to true.