Search code examples
phpangularcookiessetcookie

Set-Cookie header not creating cookie in test environment


I have a local testing application mimicking the host test.mywebsite.com on port 4200.

It makes a call to api.test.mywebsite.com (also locally hosted) to /login

The request passes, the server returns 200 and some information, and along with it it sets this header which I see in the response headers:

Set-Cookie: refreshToken={JWT here}; expires=Sun, 23-May-2021 20:38:32 GMT; Max-Age=1296000; path=/; domain=.test.mywebsite.com; HttpOnly

This doesn't get stored in my browser (either Chrome or Firefox) and I'm trying to figure out why.

Here's some more information about my setup if needed: Angular server using ng serve --host=test.mywebsite.com to get the test frontend up on http://test.mywebsite.com:4200

Kubernetes backend running on localhost (with my hosts file redirecting api.test.mywebsite.com to 127.0.0.1) which directs the request to a PHP pod that creates the cookie using this code:

     setcookie(
        "refreshToken",          // name
        $refreshJWT->token,      // token
        $refreshJWT->expiration, // expires in 15 days
        '/',                     // path
        ".".$refreshJWT->domain, // domain
        ($refreshJWT->environmentType === "test") ? false : true, // security
        true                     // httponly
    );

I fear it's something painfully simple or an oversight somewhere, but can't for the life of me find out what. The only thing I can think of would be the port not matching with the cookie host, but as far as I know cookie domains are port-agnostic. I've tried adding :4200 to the end of the cookie domain anyway and still have the same problem.

Update: setcookie() returns true, so there's no output previous to setting the header.

Update2: I deployed it to a staging server and the problem still occurs despite no DNS trickery or proxies going on.

Update3: I've narrowed it down to a combination of my api server's Access-Control-Allow-Origin header, and my JS' use of withCredentials My Access-Control-Allow-Origin is set to *. If I send the request withCredentials as false, it returns the body to the JS but refuses the cookie. If I set withCredentials to true, it sets the cookie but refuses to allow the JS to read the body.


Solution

  • I found out the reason, for anyone who may be stumbling on this:

    The first problems was while my requests were going through and returning 200, the cookie was not being set because I didn't agree to receive a cookie on the frontend. To agree to cookies on the frontend, I had to use withCredentials.

    The second problem was on the backend, I didn't explicitly send the header Access-Control-Allow-Credentials This would allow both front and backend to agree to a cookie exchange.

    The third problem was my backend had a wildcard set for Access-Control-Allow-Origin, which my browser requires to match the current host exactly if withCredentials is used.