3

Trying to send cookie back after login request on my hobby project website. For some reason it is working when running locally i.e. http://localhost:3000. But as soon as I push my API online and try to access it through my live website, I see no cookie under Application -> Cookies -> website (using chrome). I have googled a lot and I believe I have set check off every CORS policy.

The nodeJS is running in AWS lambda and is invoked through API gateway. API GW is directed to through a cloudfront distribution (if it matters).

In my express backend I have logged my headers accordingly:

res.cookie('jwt', token, cookieOptions);
console.log('Checking cookie', res);
console.log('Checking cookie', res.cookies);

res.status(statusCode).json({
  status: 'success',
  data: {
    user
  }
});

The output of this is partially this:

'access-control-allow-origin': [ 'Access-Control-Allow-Origin', 'https://example.com' ],
 vary: [ 'Vary', 'Origin' ],
 'access-control-allow-credentials': [ 'Access-Control-Allow-Credentials', 'true' ],
 'access-control-allow-methods':
  [ 'Access-Control-Allow-Methods',
    'GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS' ],
 'access-control-allow-headers':
  [ 'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept, X-PINGOTHER' ],
 'x-ratelimit-limit': [ 'X-RateLimit-Limit', 100 ],
 'x-ratelimit-remaining': [ 'X-RateLimit-Remaining', 97 ],
 date: [ 'Date', 'Fri, 11 Dec 2020 23:20:28 GMT' ],
 'x-ratelimit-reset': [ 'X-RateLimit-Reset', 1607732145 ],
 quizappuserloggedin: [ 'QuizAppUserLoggedIn', 'false' ],
 'set-cookie':
  [ 'Set-Cookie', 'my-cookie'; Path=/; Expires=Sat, 12 Dec 2020 23:20:34 GMT; HttpOnly; Secure'

From what I can tell I have set my CORS settings correctly. From my frontend I have set:

axios.defaults.withCredentials = true;

From what I can tell I have done everything I can find in Set cookies for cross origin requests

Meaning I have doubled checked my cors settings and from the print statement it looks like the cookie is being sent. But why is the browser not picking it up?

Could post the actual site and github repo if it helps, I have been stuck here for a whole now.

UPDATE

I looked at the response headers in my browser and compared it against the headers in the backend api. From that comparison I can see that my "set-cookie" header isn't included in the response even though I can clearly see that it is included in the response from the backend:

enter image description here

UPDATE 2

I believe after further investigation that I have narrowed it down to being an CORS issue with AWS API Gateway. I looked into these, but still no luck.

How to add CORS header to AWS API Gateway response with lambda proxy integration activate

Amazon API gateway ignores set-cookie

Logs from the lambda cloudwatch right before the response is being sent by the express framework as well as cloudwatch logs from the API Gateway (response headers).

API GW cloudwatch logs of the response headers:

API GW

Lambda cloudwatch logs of the response object sent by express framework:

LAMBDA

Frankster
  • 113
  • 16
  • Are you trying to _access_ the cookie in your cross-origin frontend application (i.e., in the frontend JS code), or do you just want to make sure the cookie is returned to the backend with each request? Because the latter can be done following the steps in the link you provided, but there really is no way for front-end code to gain direct access to another origin's cookies. – Nick Dec 12 '20 at 00:08
  • I'm trying to access it in my frontend for authentication. Just what this guy is doing: https://www.youtube.com/watch?v=a5Krfkfl9MM&lc=Ugzce7gGGnlmaKMOJgt4AaABAg.9G5WzyVZ3NC9G65QiF5Awk – Frankster Dec 12 '20 at 00:16
  • He's using `httpOnly` cookies, so there's no way he's accessing them in his frontend app code. – Nick Dec 12 '20 at 00:18
  • "A cookie with the HttpOnly attribute is inaccessible to the JavaScript Document.cookie API; it is sent only to the server." https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies – Nick Dec 12 '20 at 00:18
  • Sure that is the whole point, it is "secure" from access through js. But my intention (or so I thought) was that I would create a login post request, receive a response with a cookie that is stored in the browser, which will later be automatically included with any request I make to that same domain. By "access" I didn't mean actual access through code, just to clarify. – Frankster Dec 12 '20 at 00:21
  • Yeah, which will be the case, but you if you won't see it in the list of cookies for your application that lives at another origin. The cookie gets attached when the request is made to the domain to which the cookie belongs. – Nick Dec 12 '20 at 00:24
  • Are you finding that your request object on subsequent requests no longer has the cookie? – Nick Dec 12 '20 at 00:26
  • Well the cookie never appears in the browser, ever. I just see it when running both the frontend and api locally. – Frankster Dec 12 '20 at 00:27
  • Could it be a problem that the api is running in API GW which in turn is directed through cloudfront. Does the cookie somehow "belong" to the api gw or cloudfront domain instead of my "website" – Frankster Dec 12 '20 at 00:29
  • 1
    It's important to understand that if your backend is at api.example.com and your frontend is at www.example.com, for example, then you will _never_ see api.example.com cookies in your cookie list for www.example.com. Cookies are _origin-specific_, with the exception that there is no port isolation. But even though you can't see the api.example.com cookie, it can still get attached to requests to that domain by the browser. – Nick Dec 12 '20 at 00:30
  • I believe I understand. I have my website at example.com and any request made to example.com/api/v1/* gets directed to my backend api. Perhaps I should just include the cookie in the body and store it in local storage – Frankster Dec 12 '20 at 00:32
  • If you're using an HttpOnly cookie, it should still work cross-origin. To test this out, try changing either your localhost backend or frontend to 127.0.0.1 and you'll see that the cookie still works but doesn't display in the cookie list – Nick Dec 12 '20 at 00:34
  • If I changed my frontend to 127.0.0.1 and call the api from a local instance I get a CORS error. – Frankster Dec 12 '20 at 08:54
  • Hi, did you try to add a domain to the cookie; like Domain=${Domain}; here the domain should be the domain of your app, or the app should be on a sub-domain. – G. Bahaa Dec 16 '20 at 08:28
  • yeah, I have tried on both domain and sub-domain level. – Frankster Dec 16 '20 at 18:49

1 Answers1

0

Turns out it wasn’t a CORS issue. I had simply forgotten to forward cookies from my cloudfront distribution.

Frankster
  • 113
  • 16