0

I need to send a file_get_contents() to an API endpoint with the client's cookies that are set by Wordpress to show that the user is logged into the wordpress site. I know I need to use stream_context_create() roughly as follows:

$cookies = ??? //THIS IS THE QUESTION (see answer below)!

// Create a stream
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: {$cookies}\r\n"
  )
);

$context = stream_context_create($opts);

// Open the file using the HTTP headers set above
$file = file_get_contents('http://example.dev/api/autho/', false, $context);

As you can see from the comment on the first line, I'm stuck on how to send this request so that the correct cookies are sent. I know the correct cookies are sent because I can print out $_COOKIES and see them there. But if I try to insert that same array into the headers, it doesn't work.

Thanks in advance!

ps: I've read that I should use cURL for this, but I'm not sure why and I don't know how to use it... but I'm open to the idea.

UPDATE: I got this to work. It's basically the same thing I was doing, with another important cookie . See my answer below.

emersonthis
  • 32,822
  • 59
  • 210
  • 375
  • 1
    Are you 100% sure there is no client-side (Ajax) way to do this? It would be much cleaner – Pekka Jul 31 '12 at 19:35
  • possible duplicate of [PHP - Send cookie with file_get_contents](http://stackoverflow.com/questions/3431160/php-send-cookie-with-file-get-contents) – nickb Jul 31 '12 at 19:35
  • 1
    Man, first link after googling `php curl cookies` > http://coderscult.com/php/php-curl/2008/05/20/php-curl-cookies-example/ and full php documentation for [`curl_setopt`](http://php.net/manual/en/function.curl-setopt.php) especially `CURLOPT_COOKIE` – Vyktor Jul 31 '12 at 19:37
  • @Lusitanian "ps: I've read that I should use cURL for this, but I'm not sure why and I don't know how to use it... but I'm open to the idea." < he should use it :) – Vyktor Jul 31 '12 at 19:39
  • @Vyktor *facepalm* my fault (: – Lusitanian Jul 31 '12 at 19:39
  • @Lusitanian: I'll check out the curl resource you recommended, but it not my first choice if this can be done with `file_get_contents()` @Pekk: There IS a client-side way to do it which works great, but I don't have that option. There's security issues. – emersonthis Jul 31 '12 at 21:08

4 Answers4

1

The cookies should be in the following format: Cookie: cookieone=value; cookietwo=value, that is, separated by a semicolon and space with no trailing semicolon. Loop through your cookie array, output that format, and send it.

Lusitanian
  • 11,012
  • 1
  • 41
  • 38
  • This was the first thing I tried and it didn't work. I got nothing back from the `file_get_contents`. I'm not sure why. – emersonthis Jul 31 '12 at 21:09
1

It turns out I was doing it correctly, but I didn't know that WP needs a second cookie sent in order for the request to work properly.

Here's the code that works for me:

$cookies = $_COOKIE;
$name;
$value;
foreach ($_COOKIE as $key => $cookie ) {
    if ( strpos( $key, 'wordpress_logged_in') !== FALSE ) {
        $name = $key;
        $value = $cookie;
    } 
}

// Create a stream
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: {$key}={$cookie}; wordpress_test_cookie=WP Cookie check \r\n"
  )
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://mydomain.dev/api/autho/', false, $context);

var_dump($file);

It's basically the same thing as you see in my question, but with an important addition: wordpress_test_cookie=WP Cookie check. I haven't seen it documented anywhere, but WP needs this cookie as well as the actual wordpress_logged_in cookie in order for the call to happen as an logged in user.

emersonthis
  • 32,822
  • 59
  • 210
  • 375
0

Okay, as you mentioned you should use cURL (partially it's my personal opinion, I have some bad experiences with server configuration that prohibited URL file wrappers).

A quote from manual:

A URL can be used as a filename with this function if the fopen wrappers have been enabled.

So it may happen to you that the code just won't work. On the other hand cURL is designed for fetching of remote content and provides lot of control on what's going on, how to fetch data and so on.

When you look at curl_setopt you can see how many and how detailed things you can set (but you don't have to, it's just optional when you need it).

Here's the first link after googling php curl set cookies, that's great place for you to start... Basic examples are totally trivial.

Vyktor
  • 20,559
  • 6
  • 64
  • 96
  • I tried using `curl`, just as shown in that link, but it didn't work. The returned info shows no user logged in. If I enter the API endpoint into the browser, I see the Wordpress user_id, etc. So the cookies are set correctly. – emersonthis Jul 31 '12 at 21:21
  • Do you know if/where I should see that temp file after I test that code? I testing on MAMP PRO and don't see it in Applications/MAMP/tmp/, and I'm wondering if there's a permissions issue or something, but I don't really know what I should expect. – emersonthis Jul 31 '12 at 21:27
  • Update. I found where MAMP stores the file (/private/tmp/COOKIExyz). The file doesn't show the user's logged in status: `mydomain.dev FALSE / FALSE 0 PHPSESSID 8dacd1af06a4cc75936fef743b52a8ef ` – emersonthis Jul 31 '12 at 21:35
0
$cookies = $_COOKIE;
foreach ($_COOKIE as $key => $cookie ) {
    if ( strpos( $key, 'wordpress_logged_in') !== FALSE ) {
        $name = $key;
        $value = $cookie;
        break;
    } 
}

// Create a stream
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: {$key}={$cookie}; wordpress_test_cookie=WP Cookie check\r\n"
  )
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://mydomain.dev/api/autho/', false, $context);

var_dump($file);

I didn't have points to make a comment, so I readded the code from emersonthis. In order for this to work under my configuration (php 7.0.3, wordpress 4.4.2) I HAD TO remove the last space after the "WP Cookie check" string.

Fredrik_Borgstrom
  • 2,504
  • 25
  • 32