Search code examples
angularjslaravelcookieslaravel-5.3csrf

Laravel Cookie not set despite Set-cookie header being present


We're developing a website with a REST Api (frontend in AngularJS 1.6.1, backend in Laravel 5.3). In order to add CSRF protection, our backend needs to set a backend cookie on the client with a random string. In laravel, we return this response: response("OK", 200)->cookie("csrf_token", "random_string");

The cookie is clearly being set with the response:

*Request headers*
POST /v1/auth/admin HTTP/1.1
Host: backend.test
Connection: keep-alive
Content-Length: 295
Accept: */*
Origin: http://frontend.test
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://frontend.test/login
Accept-Encoding: gzip, deflate
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4

*Response header*
HTTP/1.1 200 OK
Server: nginx/1.11.3
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: http://frontend.test
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Requested-With
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Date: Mon, 13 Feb 2017 11:46:16 GMT
Set-Cookie: csrf_token=random_string; expires=Sat, 12-Feb-2022 11:46:16 GMT; Max-Age=157680000; path=/; domain=http://backend.test; HttpOnly

However, when I go to the http://backend.test Url, no cookie is set (document.cookie in the console returns null). The backend cannot see the cookie either: dd($request->cookie("csrf_token") returns null.

It doesn't work even if we omit the domain. Any ideas?


Solution

  • For Angular to send the cookie along with the request in a CORS (Cross Origin Resource Sharing request), you need to set, in your config with $httpProvider injected as a dependency:

    .config(function ($httpProvider) {
        $httpProvider.defaults.withCredentials = true;
        //rest of route code
    }