0

Site works great when backend and frontend are deployed locally (on two different ports) but cookies won't send when I run it on Vercel. I even tried running the front-end locally using the back-end that I deployed on Vercel and the request still didn't contain cookies.

This is what the request looks like using the local backend: enter image description here

And with the Vercel-deployed backend: enter image description here

My vercel.json file looks like this:

{
  "version": 2,
  "builds": [
    {
      "src": "*.js",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "/",
      "methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
      "headers": {
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Allow-Origin": "http://localhost:3000",
        "Access-Control-Allow-Methods": "GET,OPTIONS,PATCH,DELETE,POST,PUT",
        "Access-Control-Allow-Headers": "*"
      }
    }
  ]
}

And I've configured axios to use credentials and set credentials to true in the Express index.js file. And, set-cookie works:

enter image description here

Would appreciate any help.

I've tried changing the headers a bunch and no combination seems to work.

5
  • Hi, Thank you for the question. Unlike in a development env., express server in a production env. mostly be running behind a proxy. Therefore it must trust the proxy to get the client request forwarded properly. If this is not happening, the express server may behave differently in production than it in a development. Therefore please try to set trust proxy as app.set('trust proxy', true). Commented Jul 6 at 3:43
  • You can read more on this topic here: expressjs.com/en/guide/…. Also here expressjs.com/en/resources/middleware/cookie-session.html Commented Jul 6 at 3:43
  • @WeDoTheBest4You Hi, thank you so much for your help! I did add the line app.set('trust proxy', true) but it doesn't seem to have any effect. I looked at the article about cookie-session but didn't quite understand. Right now the only thing I'm using for cookies is cookie-parser. How should I be using cookie-session, if it's necessary?
    – Josephine
    Commented Jul 8 at 18:00
  • Hi, As i understand at this point in time, Vercel uses a mechanism - rewrites in place of a proxy server. Therefore the trust proxy setup does not have any effect. I did not know it earlier. response.cookie method and cookie-parser middleware are the two essential ways to handle cookies. While response.cookie writes cookies to outgoing requests or responses, cookie-parser reads cookies from Incoming requests. I referred you to cookie-session since this middleware has some impact when there is a proxy server. However this is not the case with Vercel. Commented Jul 12 at 11:18
  • ...It is not a necessary in dealing with cookies. It is mainly used for the cases wherein user session tracking in required. Commented Jul 12 at 11:27

1 Answer 1

0

Please see below a minimal code example showing a cookie passing through a request-response cycle. This example has been deployed in Vercel and it works there. The output shown below is taken from a deployment preview. Please see if it is useful to check with your code to find out any differences in the setup.

Please also note that this example uses an HTML page as its frontend. It is being served from the same express server wherein the API is also hosted. Therefore there is no CORS involved in it.

Note:

Initially I tried to create another example with a CORS scenario. However, I could not make it deployed successfully in Vercel as its CORS setup did not match.

index.js

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();

app.use(express.static('public'));

app.use(cookieParser());

app.get('/cookie', (req, res) => {
  let response;

  if (req.cookies?.somecookie) {
    response = 'Same cookie: A cookie received and the same sent to client';
  } else {
    res.cookie('somecookie', 'cookie text');
    response = 'New cookie: A new cookie created and sent to the client';
  }

  res.send(response);
});

app.listen(4000, () => {
  console.log(`L@4000`);
});

module.exports = app;

Index.html

<!DOCTYPE html>
<html>
  <head>
    Cookie tests header
  </head>
  <body>
    <br />
    <br />
    Cookie tests body
    <br />
    <br />
    <p></p>
  </body>
  <script>
    const p = document.querySelector('p');

    fetch('/cookie', {
      method: 'GET',
    })
      .then((response) => {
        if (!response.ok) {
          p.textContent = 'Error occured';
        }
        return response.text();
      })
      .then((data) => {
        p.textContent = data;
      });
  </script>
</html>

vercel.json

{ "version": 2, "rewrites": [{ "source": "/(.*)", "destination": "/api" }] }

Test results:

  1. On loading the site, the API creates a new cookie as shown in the browser screenshot below.

enter image description here

  1. On refreshing the site, the API sends the same cookie back, which shows that the same cookie passes through a request-response cycle. enter image description here
1
  • Thank you for your confirmation. This was a general answer to the question, if possible, kindly help us to know the actual cause of failure and the fix you have applied in your case. If the same is updated as a self answer, as a comment or as an update in the question itself, it would help others as well. Commented Jul 16 at 2:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.