简体   繁体   中英

How does PHP parse raw cookies into $_COOKIE?

I have an issue with cross-domain AJAX requests.

Three servers are involved in this issue. We can call them A1 , A2 , and B .

A1 and A2 are running the same application code. They are two staging instances of the same web application. B is another web application.

We need to perform a cross-domain AJAX request from the A web application to the B application. We experimented with enabling CORS but had difficulties getting it working satisfactorily in IE <= 8, so now we are using an nginx proxying rule. The flow is therefore: browser ajax request -> A1 or A2 -> nginx proxied -> B

B is stateful and requires the user's session cookie to function.

What we're seeing is that this works properly when using server A1 , but when using server A2 , B can't pull out the cookies.

I have looked at the headers for the requests coming from A1 and A2 and they are the same. Both have the cookies line in the header, both have the same origin, etc.

On B what we see is that $_COOKIE['session_key'] is empty when the request comes from A2 but properly filled out when the request comes from A1 .

The weird thing is that it's only missing pulling one particular cookie key out of the cookies in the header, and only when the request comes from A2 . It parses every other cookie in the headers from A2 fine, it just can't parse the user's session cookie for some reason but it can just fine if the request comes from A1 .

I have used tcpdump and taken pcaps of each of these and diffed them and nothing in the headers looks particularly different.

I found this Stack Overflow question and people said it was because his cookie header string was too long: What could cause cookie to not be set in $_COOKIE when it's in $_SERVER I don't think that's too long as mine is only 249 characters long, in both the successful and failing case.

I'm at the point where I'm considering ripping the cookies out of $_SERVER and manually parsing them but that sounds really stupid and I'd prefer to figure out the underlying issue.

One issue when using IE<=8 is something called P3P . I have found that dropping in a P3P header into pages that accept your AJAX/JSON request (server B in your instance) will solve this problem:

header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');

As for server A2 not sending $_COOKIE requests to server B , I would recommend sending the request using _GET to some sort of init page on server B . This way it can be processed, and stored on server B . Then for all remaining pages where this information must be present, you can look to server B to determine if the information has been sent, or continuously send the _GET data to each page and compare it with the information already on hand. As a reminder, this info should be strictly monitored as it will be much easier to modify.

I apologize, I realize that this doesn't fix the issue, but could offer an alternative solution.

PHP wasn't at fault here.

We were using Kohana and it had some code run at initialization to attempt to add additional security to the session cookie. The code in question verified that the IP address recorded in the session on the server side matched the IP address sent in the request headers.

Due to our network configuration, I received an external IP always when contacting server B, an internal IP when contacting A2, and an external IP when contacting A1.

When A2 forwarded the request with the internal IP to B, it triggered Kohana's IP-based cookie protection as the cookie was created with my external IP but now trying to be used by my internal IP.

Some time ago, I had to do Cross-Domain ajax requests. Obviously, I had the same issue when I tried setting a header to "allow x-domain ajax" with IE (don't remember exactly the header name).

What I did to get this sorted, is to use CURL between server's ajaxs. So in that way, my ajax scripts (written in PHP), were able to exchange data through the servers via JSON + CURL, sending by doing a CURL POST, and retriving data via a CURL GET, regardless of what domains were involved.

Please excuse me, maybe this is not exactly the answer you needed, but, IMO, this could help someone looking for Cross-Site ajax.

Use GET between servers; that's all. And build up a way to hash the get so that if a server fails to complete the request, the user doesn't see the actual cookie content pulled

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM