'req.cookies returns undefined but cookies are set

I am using cookie-parser in my express app. When the root page is requested I set a random number on the cookie using res.cookie(name, value) and it sets it fine (I checked on my browser console). But when I try to log req.cookie it always returns undefined.

Here's my code:

routes.js

var express = require('express')
var router = express.Router()

var movieTrailer = require('movie-trailer');

var Promise = require('bluebird');
var logs = require('log-switch');
var fs = require('fs');
//var cookieParser = require('cookie-parser');

//Setup x-ray for scraping
var Xray = require('x-ray');
var x = Xray();

var debug = false;

router.get('/', (req, res) => {
  console.log('Page requested!');
  console.log('Cookies: ', req.headers.cookies); // For some reason this returns undefined

  var scrapeMovies = function(){
    return new Promise((resolve, reject) =>{
      fs.readFile('moviesRT.json', (err,data) =>{
        var movies = JSON.parse(data);
        resolve(movies);
      });
    });
  };

scrapeMovies().then(
    movies => {
      var randomInt = Math.floor(Math.random() * movies.length);
      res.cookie('randomInt', randomInt);
      var randomMovie = movies[randomInt];
      movieTrailer(randomMovie.title, (err, url) =>{
        console.log('Requesting trailer: ', randomMovie.title);
        if(err) throw err;
        var embedUrl = url.replace('watch?v=','embed/');
        console.log('Video ID: ', url.slice(32,url.length));
        randomMovie.trailerURL = embedUrl; //Add the embed URL to the randomMovie object before rendering it
        res.render('main',randomMovie,
        (err, html) =>
        {
          if(err) throw err;
          console.log('Rendering...');
          res.send(html);
          console.log("Done!");
        });
      });
    });

});

module.exports = router;

app.js

const express = require('express');

//Define app and settings
const app = express();
const exphbs = require('express-handlebars');
var cookieParser = require('cookie-parser');
const port = 3000;

var routes = require('./routes');

var debug = true;

app.use('/', routes);
app.use(express.static('public'));
app.use(cookieParser());
//app.use(cookieParser());

//View engine
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');

app.listen(port, function () {
  console.log(`Server Starts on ${port}`);
  if(!debug) logs.disable(); //Disable logging if debug variable is false
});


Solution 1:[1]

You either want to check req.headers.cookie which will be set by express.

Or if you want to use the the parsed result of the cookie-parse middleware that is stored inreq.cookies then your problem is the order in which you register your routes and the middleware.

app.use('/', routes);
app.use(express.static('public'));
app.use(cookieParser());

The parsing of the cookie is done after the routes in routes have ben executed.

You need to move the cookieParser() before the route where you want to use it.

app.use(cookieParser());
app.use('/', routes);
app.use(express.static('public'));

Solution 2:[2]

This solved my problem:

Basically when you are sending a request to the server from client-side, make sure you add withCredentials: true. For example

{
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }),
    'withCredentials':true
  };

Solution 3:[3]

This happened to me, when I sent a PUT request from the client-side (Angular) without passing the body object.

I was doing this (second argument missing):

requestBranchEditPermission() {
  return this.http.put<IPutProfile>(`${this.api}/some-endpoint`, this.options).toPromise();
}

instead of this:

requestBranchEditPermission() {
  return this.http.put<IPutProfile>(`${this.api}/some-endpoint`, {}, this.options).toPromise();
}

Solution 4:[4]

You will need to read the cookies as req.cookies['cookie-name'] and set the cookies as resInit.cookie('cookie-name', 'cookie-value')

Solution 5:[5]

This worked for me

in the frontend add credentials : 'include' as an option to your fetch API

A more elaborated code below for a get request

fetch('url', {credentials: 'include'})
.then(res => res.json())
.then(data => //do something with the data)
.catch(err => console.log(err.message));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 t.niese
Solution 2 LukeWarm2897
Solution 3 King James Enejo
Solution 4 Atlas01
Solution 5 Octagod