Dear all,

I have a (non-Drupal) web application on http://app.mydomain.org that is making a JSONP request to a Services 3 resource on a Drupal site http://drupal.mydomain.org. The resource is only accessible when the user is logged in.

On Chrome, Firefox, and Safari, this work perfectly: If the user has logged into Drupal and afterwords loads the app, the resource is fetched successfully. However, in Internet Explorer the request produces an Access Denied.

I used

error_log(print_r($_COOKIE, true));

to print out the cookies in the requests to Services. In case of Chrome/Firefox/Safari, the session cookie is printed, in case of IE, the cookie is not included. My conclusion is that Services therefore thinks the user is not logged in.

My question: If some browsers do not send the session cookie, is there a way I can pass it in the JSONP request? In my application I do know the user's session ID for Drupal so I am hoping for some way to send it to Drupal in the JSONP request, a la ?sessid=DRUPALSESSIONID maybe.

Thanks!
Kaspar

Remarks:

  • I am using JSONP (and not JSON) to overcome the Same-Origin-Policy. I know about Cross-Origin Resource Sharing but since I need to support Internet Explorer 6+, I cannot use it.
  • I have tried adding special headers header('P3P: CP="CAO PSA OUR"'); for Internet Explorer, see http://stackoverflow.com/questions/2086512/jsonp-php-session-does-not-remain-constant, without success.
  • My application knows the Drupal session ID because the application redirects the user to Drupal for login and if Drupal recognizes the user, it sends him/her back to http://app.mydomain.org?sessid=...

Comments

Anonymous’s picture

I'm having the same issue. How do I pass the session id for JSON type callbacks?

7wonders’s picture

In android I store the session as follows:

editor.putString("Cookie", sessionname + "=" + sessionid);

Along with the timestamp. Then if doing subsequent requests and the session is still valid I set it as a cookie header:

post.setHeader("Cookie", cookie);

So basically it is passing the session as session_name=sessid as a cookie header. Not sure if that helps at all.

Anonymous’s picture

In android I discovered the CookieStore. If you use that when calling the login method, then the cookie information including session id are stored. Then you just need to use that CookieStore for each subsequent call. Hope that helps.

tpainton’s picture

Can you elaborate on CookieStore?? Maybe an example? Thanks a ton.

Anonymous’s picture

7wonders’s picture

You can basically do it like this:

post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
CookieStore cookieStore = new BasicCookieStore();
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
// Execute
HttpClient mHttpClient = new DefaultHttpClient();
HttpResponse response = null;
response = mHttpClient.execute(post, localContext);
tpainton’s picture

@WildKatana, I don't see any reference to CookieStore in that example.

7wonders’s picture

Its at the top of the questions snippet.

ygerasimov’s picture

@hbfkf please advise whether your problem with IE is still valid. I am not quite sure how your web application works for your users. As I understood first users should login to drupal site (that hosts services) and then they open web application. Could you please clarify what language this web application is written in and how it communicates with services? How it passes cookies?

This will help to understand the architecture and possibly find solution for your case.

metow’s picture

I am also having problem with the cookie header (I am using Titanium mobile development environment):

after a succesfull login
I'm getting session name , session id as well as all the other log-in info via the json object.
Next I'm trying to access a node using the code :

xhr = Titanium.Network.createHTTPClient();
xhr.open('GET','http://mywebsite/rest/node/'+nodeid+'.json');
xhr.setRequestHeader('Content-Type','application/json');	
xhr.setRequestHeader('Cookie',sessionname+'='+sessid);
xhr.send();
	xhr.onload = function() {
		var jsonObject = JSON.parse(this.responseText);
		Ti.API.info(' jsonObject');	
	};

but I'm getting "Unauthorized: Access denied for 0 user 'anonymous'" error. It seems as if I'm somewhere wrong in sending the cookie information.
because using the adress through my laptop 'http://mywebsite/rest/node/481.json" returns the node info when the user is logged in, if not returns null.
So there's nothing wrong with the adress, or the users priveleges to access this node.

Any help will be much appreciated.

metow’s picture

I'm only sending ("Cookie", sessionname + "=" + sessionid) as the header and not get autherized.
So what about the timestamp? what's it and how do i send it?

7wonders’s picture

Have you looked into Drupanium metow?

ygerasimov’s picture

@hbfkf have you resolved your issue with jsonp calls? Please share your solution if have any.

Regarding passing session to drupal, it should be set in cookies.

marcus178’s picture

Does anyone have a solution for this, I have found the following works for system/connect.json

var url = rest_path + 'system/connect.json';

	var xhr = Titanium.Network.createHTTPClient({
		timeout : timeout
	});

	xhr.onload = function() {

		if (xhr.status == 200) {

			var response = xhr.responseText;

			var data = JSON.parse(response);
			
			onSuccess(data);
		}
	}
	xhr.open("POST", url);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xhr.setRequestHeader("Cookie", Titanium.App.Properties.getString("userSessionName") + '=' + Titanium.App.Properties.getString("userSessionId"));
	xhr.send();

but when using GET it does not work. I get Bad Sever =>Unauthorized: Access denied for user 0 "anonymous"

var url = rest_path + 'views/app_membership_info?args=' + uid;
	// Create a new connection in the variable xhr
	var xhr = Titanium.Network.createHTTPClient({timeout: timeout});
	xhr.onload = function() {
		var statusCode = xhr.status;
		
		if(statusCode == 200) {
			var response = xhr.responseText;
			var data = JSON.parse(response);
			onSuccess(data, statusCode);
		}
	}

	xhr.open("GET", url);
	xhr.setRequestHeader('Content-Type','application/json; charset=utf-8');
	xhr.setRequestHeader("Cookie", Titanium.App.Properties.getString("userSessionName") + '=' + Titanium.App.Properties.getString("userSessionId"));	
	xhr.send(); 
kylebrowning’s picture

Status: Active » Closed (works as designed)

Send it as a header.