Meteor 1.3 Beta 11 - Setting Cookies From Cordova on Android


#1

Hello everybody,

TL;DR: We want to set cookies on our XHR (AJAX) - Requests to the server from Android Platform 23 Cordova Devices.

(Cross-posted to https://github.com/meteor/meteor/issues/6050#issuecomment-189626424)


Longer Version:

We want / need to authenticate our user from our cordova app on our server. The problem is we’re using a custom request handler to upload files (a fork of https://github.com/vsivsi/meteor-file-collection). The way to supply user authentication information we used so far was using the cordova-cookie-master-package (https://github.com/kristianhristov/cordova-cookie-master) to set these cookies on XHR (AJAX) Requests requests to the server.

With Meteor 1.3 Beta 11 the android SDK Platform API Version has been upped to 23. Unfortunately, with this the Apache HTTP Client support has been nixed: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client on which the cookie-master - package relied to set the cookies.

So the question is now: How can we send additional authentication information to the Server?

We could probably encode it in the request URL, which is what I’ll be doing as a temporary hack; But besides that it seems that our options are very limited (most outgoing headers seem to be filtered / whitelisted?).

It’d be nice if there’d be a way to add the cookie information back to the XHR Requests.

One temporary workaround would be to add the following to the build-extras.gradle.txt - file:

ext.postBuildExtras = 
{
android {
    useLibrary 'org.apache.http.legacy'
    println('useLibrary org.apache.http.legacy');
    }
}

to add the legacy support for HTTP back into the project for android. But I don’t think there’s a setting in mobile_config.js to do that, or is there?

Could anybody point me to some workable options? I’d prefer to stick to the meteor build process in the most part, but if there are some workarounds including step-by-step-instructions i’d be interested too.


[Solved] Apollo and iOS 10
#2

(Already answered on the issue, but also posting here because it might help other people.)

I did some testing, and with the right CORS headers it seems you can definitely send additional headers (tested on iOS 9 and Android 5.1). You can also send cookies, but you can’t set cookies for other domains from JavaScript, so the server would have needed to set the cookie in a previous response. I’ve included some sample code, but you may want to have a look here for more details.

On the client:

var xhr = new XMLHttpRequest();
xhr.open("GET",  __meteor_runtime_config__.ROOT_URL + "cookietest", true);
// Only needed for cookies
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "bla");
xhr.onreadystatechange = function() {
  if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
    console.log(xhr.responseText);
  }
};
xhr.send();

On the server:

WebApp.connectHandlers.use("/cookietest", function(request, response, next) {
  // We need to echo the origin provided in the request
  var origin = request.headers.origin;
  if (origin) {
    response.setHeader("Access-Control-Allow-Origin", origin);
  }

  // Only needed for cookies
  response.setHeader("Access-Control-Allow-Credentials", "true");

  // For the preflight
  if (request.method == "OPTIONS") {
    response.setHeader("Access-Control-Allow-Headers", "authorization");
  }

  response.writeHead(200, {'Content-type': 'text/plain'});

  // For the actual response
  if (request.method == "GET") {
    var authorization = request.headers.authorization;
    response.write("Hello " + authorization);
  }
  response.end();
});

#3

(Also answered on the actual issue as well)

Hello @martijnwalraven , you’re right, thank you very much!

CORS is of course possible the way you do it, and I should be able to supply the authentication information as in your example. I was missing the “Access-Control-Allow-Headers”, “authorization” - header I think.

This means I won’t need the cookies for my current endeavor, which is nice!


About being able to set cookies via a server response: That’s great, but probably not what we’d need.

But you think it should be possible to make Cross-Domain Requests from Cordova with credentials and in return we’d get those cookies set persistently for our app? That’d be a nice thing to have in any case!


So, thank you very much for your help, I’ll waltz through the third-party-code on monday and patch the heck out of it, and we’ll be using the glorious Meteor Beta 1.3! :smiley:


#4

Hi All,

I just wanted to add some info here. There is a way to set your cookies client side for a cordova app that can be much simpler than the technique described here.

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

It just works!