7

I am facing the issue : on every request new sessionID is getting created. Can someone throw light at this ?

Versions I am using:

NODE VERSION: v6.10.3 NPM VERSION: 3.10.10 express@4.15.3 express-session@1.15.3

Also what is the default value for maxAge if I am not setting the cookie specifically ? Not sure if its required.

Do you see any issue with the code below ? Please assist as I am stuck.

      var app = express();
        app.use(express.static(path.join(__dirname, 'landing')));
        app.use(bodyparser.json());
        app.set('trust proxy', 1) // trust first proxy
        app.use(session({
        secret: 'keyboard cat',
        resave: false,
        saveUninitialized: true,
        cookie: {secure: true}
    }))

    app.get('/', function (req, res) {
        res.sendFile(path.join(__dirname, 'landing', 'index.html'));
    });


    var contextPath = '/myportal';

    //UI url
    app.get(contextPath, function (req, res) {
        var reqValues;
              logger.info("req sessionID is :::" + req.sessionID);
           // do something
                } 
        app.use(express.static(path.join(__dirname, 'build'))); //react UI path
        res.sendFile(path.join(__dirname, 'build', 'index.html'));
  }    

    //health check url
    app.get(contextPath + '/health', function (req, res) {
        logger.info("env is " + env);
        logger.info("myportal health is ok");
        res.send('Health Ok!\n');
    });
Nitin Lodhe
  • 235
  • 1
  • 6
  • 14
  • Are you read [manual](https://github.com/expressjs/session#cookiesecure)? – Aikon Mogwai Jul 03 '17 at 23:38
  • Yes I have gone through the doc and that's how I was trying but unfortunately its not working for me. Wondering what I am missing here. – Nitin Lodhe Jul 03 '17 at 23:56
  • 1
    You must use [`https`](https://stackoverflow.com/a/11745114/6121703)-express. – Aikon Mogwai Jul 04 '17 at 09:15
  • thanks Aikon, yes I am already using that since I am trying to deploy it on the server where https is enabled. sorry code was growing big so could not provide those details in the initial question – Nitin Lodhe Jul 04 '17 at 14:40
  • My application is single sign on protected so SSO is providing me the unique session id which I can use instead of relying on the node js session id – Nitin Lodhe Mar 03 '18 at 15:26
  • 1
    PALLAMOLLA SAI described it correctly - I was facing the same problem. To summerize it to nutshell - you probably used post which, by default doesn't send the cookie. Either use get, or make a post request with the appropriate header which will send the cookie. You may need to verify that cookie-parser is also defined in your node server – Guy E Aug 21 '19 at 13:10

2 Answers2

7

If still anyone is looking for an answer. (After working a lot following code worked for me. correct me if I am wrong)

REASON: express session stores sessionID in cookie and it will set that cookie in frontend(browser and you can see that cookie called connect.sid in browser) from backend(server). Whenever any request comes from browser first it will check for that cookie(in which sessionID is stored.) If it finds the cookie it doesn't create new session otherwise it will create again a new session.(you can check it by logging req.sessionID in requests)

SOLUTION: To overcome this for every request we are making from frontend(browser) we have to send that cookie to backend(server). Server will automatically parse cookie and doesn't create any new session for every request.

I was using axios for request calls in which for every request I was adding {withCredentals:true} so that browser can send cookies to backend server(automatically). Following code was worked for me.

app.js

require('dotenv').config({path:'./config.env'});

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors=require('cors');
const uuid = require('uuid/v4')
const cookieParser = require('cookie-parser');
const session = require('express-session');
var FileStore = require('session-file-store')(session);

app.use(cors({
 origin:[process.env.ORIGIN],//frontend server localhost:8080
 methods:['GET','POST','PUT','DELETE'],
 credentials: true // enable set cookie
}));

app.use(cookieParser(process.env.SESSIONSECRET)); // any string ex: 'keyboard cat'
app.use(session({
  secret: process.env.SESSIONSECRET,
  store:new FileStore,
  cookie:{
    maxAge:36000,
    httpOnly:false,
    secure:false // for normal http connection if https is there we have to set it to true
    },
  resave: false,
  saveUninitialized: true
})) 

app.use(function(req, res, next) {

res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
res.header("Access-Control-Allow-Origin", process.env.ORIGIN);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-   Type, Accept, Authorization");
next();
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

// rest of code is your mongo connection

axios rest calls::

 axios.defaults.withCredentials = true;
 axios.get('http://localhost:8080/getDetails',{
           headers:{
                    withCredentials:true,

                   }
  });
Pallamolla Sai
  • 2,337
  • 1
  • 13
  • 14
2

it's a cookie problem

create a env for development and production

const SessionCookie = process.env.NODE_ENV == "dev" ? {
    secure: false,
    sameSite: "lax",
    maxAge: 1000 * 60 * 60 * 60 * 24 * 2//2 day
} : {
    secure: true,
    sameSite: "none",
    maxAge: 1000 * 60 * 60 * 60 * 24 * 2//2 day
}

app.set('trust proxy', 1) // trust first proxy
app.use(expressSession({
    name: "test-me-esc",
    secret: 'keyboard cat',
    store: new FileStore({}),//change your store here.
    resave: false,
    saveUninitialized: false,
    cookie: { ...SessionCookie } as any
}))

this will work on localhost: chrome, brave, firefox.

Mr Joker
  • 21
  • 4