Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ncovill's avatar

API level Laravel 5.3 Cookies not working when called via Static PHP Website

I have looked all over but can't seem to find anyone having this issue or even similar to it.

I have an API I am building with Laravel 5.3. This simply spits out data as JSON and the main site is just a static PHP website which essentially uses file_get_contents to grab said data from the API and my ApiResponse class handles decoding and all that fun stuff for it.

URL's for them are:

api.site.loc
www.site.loc

ApiResponse method used by www.site.loc to consume the API:

 public function response( $url, $page = null )
  {
    $page = $this->setPageQuery( $page );

    $data = file_get_contents( $this->apiUrl . $url . $page );
    $json = json_decode( $data );

    return $json;
  }

CORS is set up and such on the Laravel app, so I don't believe that's the issue since I have no other problems calling out to the API layer via www.site.loc

In my Cors.php Middleware:

public function handle( $request, Closure $next )
{
    if ( $request->isMethod( 'options' ) ) {
        return response( '', 200 )
               ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
               ->header('Access-Control-Allow-Headers', 'accept, content-type, x-xsrf-token, x-csrf-token'); // Add any required headers here
    }
    return $next( $request );
}

Quick explanation on what this is doing: A post belongs to a category, and a category can have many posts. So this is simply taking the cookie, which is an array of category id's, and not including said categories in the post collection.

The scope for hiding categories in my Post Model on Laravel:

public function scopeHideCategories( $query )
{
  $cookie = Cookie::get( 'mcathide' ); // this is an array of category id's

  return $query->whereNotIn( 'category_id', $cookie );
}

And the PostController on Laravel:

$posts = Post::hideCategories()->paginate( $this->postsPerPage );

return $this->respondWithPagination( $posts, [
  'posts' => $this->postTransformer->transformCollection( $posts->all() )
]);

This is working fine on the API layer, filters out categories beautifully, but when www.site.loc calls out to the API layer, it seems as though the cookie is lost, and or isn't being translated correctly anymore? This results in the www.site.loc erroring out to "HTTP request failed! HTTP/1.0 500 Internal Server Error."

The respondWithPagination is just a method I have set up to pass data to response()->json($data, $statusCode, $headers). Is there headers I am missing or something?

I know I have the cookies domain set up right via the config/sessions in Laravel, and I confirmed it via both URL's, the domain for the cookie is in fact .site.loc.

It's got to be something dumb that I'm missing (and I'm sure it is).

Update: What's even more weird is there is indeed a Request Header for Cookie:mcathide=eyJpdiI6Ik5kUHZLSGJCNnNWbEF6ejdkMHhZNFE9PSIsInZhbHVlIjoia25JNm5SR3h6akY0UkUxZE5mKzFZUT09IiwibWFjIjoiYjMyZmY3MDAzOWYyMDUxMzBmNzZiZWM3YTRhYTIwNzMzZGViOGExYmQ1MjlkNzhkZWQ4YjhmZDgzYTM3YTg4ZiJ9; PHPSESSID=5bf77496d6d766495f9826048ee1597a; laravel_session=eyJpdiI6IkEwWE1VQnVBZ0x2TUlFQVdZMldDQ2c9PSIsInZhbHVlIjoiUVkzQUxtV0U2RWtKWGRWMkxZTzhKNGpvVkgwOWp6WU1QdFZpNk1CUVI3ZTlpRWY0UldkdW43ZzMrSDhmb3ZvaTFBbkxEUWRBYXlYRTJxOHpYUkZ2TUE9PSIsIm1hYyI6Ijg3NTI3OGQyZjQ2Njc4NTc4NzhmMzY0ZTk3YTk5Yjk3YWQ5OGM2YmUyNzc5MDIxYWUwYTk0OGEwMThkNDkzMmQifQ%3D%3D

0 likes
3 replies
developernator's avatar

Try some of the edits that I made to this version of passport in order to make work on iis:

https://github.com/jeremykenedy/passportiis

specifically:

    'api' => [
            'throttle:60,1',
            'bindings',
            'auth:api',
        ]

And make sure your certificates are generated with: php artisan passport:install

ncovill's avatar

Thanks for the quick response! I'm actually not even using Passport. This is literally just an API for my web apps (maybe mobile app in the future), so I don't need a full system for others to have access. I might be thinking of it wrong, but do I need to use Passport anyway? Maybe that's what I'm missing.

Although as I mentioned, my main site consumes the API JSON fine, other than this little issue I'm having with cookies :/

ncovill's avatar
ncovill
OP
Best Answer
Level 4

Just found something interesting...by attaching the stream_context_create it actually works.

    $context = stream_context_create([
      'http'=>[
        'method'=>"GET",
        'header'=>"Accept-language: en\r\n".
                  "Cookie: mcathide=eyJpdiI6IjdCckZOZ0dRbm5JUGtURk50cG55Vnc9PSIsInZhbHVlIjoialBhN0x0UkxGMXVjZHREWERBajFnT2J0VEVSb0VlQzFtZDlreXNWeFlDQT0iLCJtYWMiOiI1ZjkxMzZhODczNmNiZmFhYTI4MGE1OWRhOTA4ZmQxMzlhNGFlM2I1NzVhMGE5MTgyMjBhNDIxNDMyNGQ2ZWMyIn0\r\n"
      ]
    ]);

However, that cookie value changes anytime it's updated, so clearly it's not the full solution, lol.

For anyone struggling with a similar issue in the future, the end solution had nothing to do with the Laravel API, but on the consumer site, in this case www.site.loc just had to store the cookie in a variable:

Final response() method:

  public function response( $url, $page = null )
  {
    $page = $this->setPageQuery( $page );

    $cookie = Cookie::get( 'mcathide' );
    $context = stream_context_create([
      'http'=>[
        'method'=>"GET",
        'header'=>"Accept-language: en\r\n".
                  "Cookie: mcathide={$cookie}\r\n"
      ]
    ]);

    $data = file_get_contents( $this->apiUrl . $url . $page, false, $context );
    $json = json_decode( $data );

    return $json;
  }
1 like

Please or to participate in this conversation.