emersonthis
emersonthis

Reputation: 33378

How to use file_get_contents() with a Wordpress user's cookies

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.

Upvotes: 0

Views: 4298

Answers (4)

Fredrik_Borgstrom
Fredrik_Borgstrom

Reputation: 3258

$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.

Upvotes: 0

emersonthis
emersonthis

Reputation: 33378

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.

Upvotes: 1

Vyktor
Vyktor

Reputation: 21007

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.

Upvotes: 0

Lusitanian
Lusitanian

Reputation: 11132

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.

Upvotes: 1

Related Questions