I have a site with a separate REST API on a subdomain, e.g. api.mysite.com, that I send CRUD requests to. The API sub-domain has this filter adding the appropriate headers to the response:
// Simple CORS handling
Route::filter('cors', function($route, $request, $response) {
$origin = Request::header('Origin');
$host = parse_url($origin, PHP_URL_HOST);
// Don't send response for external domains.
if (!in_array($host, Config::get('domains'))) {
App::abort();
}
$response->headers->set('Access-Control-Allow-Origin', $origin);
$response->headers->set('Access-Control-Allow-Headers', 'Accept, Accept-Encoding, Accept-Language, Content-Length, Content-Type');
$response->headers->set('Access-Control-Allow-Methods', 'DELETE, GET, PATCH, POST, PUT');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
});
I'm also setting crossdomain: true
and xhrFields: { withCredentials: true }
on my jQuery $.ajax
request. The requests manage to go through to the server, hit the appropriate routes, etc, but something is going wrong with the authentication process. Every time, Laravel acts as if the user hasn't logged in, causing requests to Auth::user()
to return null. Inspecting the requests in Firebug shows that the Cookie
header is sent in the request with the Laravel session id, but the server responds with SetCookie
, as if trying to start a new session. I'm probably doing something dumb here, but I'm at my wits end trying to determine just what.
Update: From some debugging, I've found something interesting out. Not sure what it means, yet. To get to the page in question, the user must be logged in. Therefore, there is a laravel_session cookie in the browser when the page loads. I then send off a couple of (cross-domain) AJAX requests by interacting with the page. The first request has no cookie set at all and gets a new laravel_session cookie set from the server. The second request then includes that cookie, but the response to it sends back yet another new cookie, as if the back-end never got the memo about the first. I'm starting to wonder if this isn't something to do with cookie domains or some-such.
I finally figured it out.
First of all, the xhr and route filter were both configured correctly. The root cause of this problem was definitely a cookie issue.
The cookie domain for laravel_session was not initially set. Browsers interpret that to be a short-hand for "current domain". That is, app.mysite.com What I needed to do was explicitly set the value in Laravel's session.domain
configuration to be ".mysite.com" That way, the same session cookie becomes available to app.mysite.com, api.mysite.com, and any other sub-domains of mysite.com Problem solved!
That said, there were two gotchas that I tripped over on my way to this solution:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With