2

I'm new to express and i'm trying to save some data in session and then retrieve it in another query. My client app is an AngularJS app.

    var express = require('express');
    var path = require('path');
    var favicon = require('serve-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');
    var cookieSession = require('cookie-session');
    app.use(cookieParser());
    app.use(cookieSession({
      name: 'session',
      keys: ['mySecret']
    }));
    app.use(bodyParser.json());

When retrieving session, it's always an empty object {} What can be the cause ? Thank you !

EDIT

This my app.js now

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
//var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var cookieSession = require('cookie-session');
var methodOverride = require('method-override');

var session = require('express-session');

//Services
var routes = require('./routes/index');
var users = require('./routes/users');
var typesOperateurs = require('./routes/typesOperateurs');
var domains = require('./routes/domains');
var categories = require('./routes/categories');
var donnees = require('./routes/donnees');
var arcepData = require('./routes/arcepData');
var generalData = require('./routes/generalData');

var app = express();

var properties = require('./configs/properties');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//app.use(cookieParser('arcepSecret'));
/*app.use(cookieSession({
      name: 'session',
      keys: ['arcepSecret'],
          httpOnly : false
    }));*/
app.use(session({
    secret:'arcepSecret',
    resave: true,
    saveUninitialized: true,
    name : 'arcep.sid'
}));
app.use(bodyParser.json());
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', properties.clientHost);

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});
//app.use(methodOverride);

//app.use(express.static(path.join(__dirname, 'public')));

//storing models
app.use(function(req, res, next) {  
      req.models = app.models;  
      next();
    });

// Routes
app.use('/arcep', routes);
app.use('/arcep/users', users);
app.use('/arcep/typesOperateurs', typesOperateurs);
app.use('/arcep/domains', domains);
app.use('/arcep/categories', categories);
app.use('/arcep/donnees', donnees);
app.use('/arcep/arcep_data', arcepData);
app.use('/arcep/general_data', generalData);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});



module.exports = app;

I'm populating the session inside

router.post('/link1', function (req, res, next) {
  req.session.name = 'khalil';
});

And i'm trying to retrieve it inside

router.post('/link2', function (req, res, next) {
        console.log(req.session);
})

EDIT2

I found that if invoke the services from the browser directly, everything goes fine, but when trying that from the client app wich is an angular app hosted on a tomcat server, the problem occures.

1
  • The solution is to allow credentials in the angular app, link Commented Sep 14, 2015 at 10:09

3 Answers 3

3

The solution is to allow credentials in the angular app.

.config(function ($routeProvider, $httpProvider) {
    $httpProvider.defaults.withCredentials = true;

$http doesn't send cookie in Requests

Sign up to request clarification or add additional context in comments.

Comments

2

I suggest you import the express-session (https://github.com/expressjs/session).

Try this:

var expressSession = require('express-session');

app.use(expressSession({secret:'somesecrettokenhere'}));

After to set and get the values in session:

app.get('/', function(req, res) {
  req.session.hello_message = "Hello world";
  res.send(req.session.hello_message);
});

The session variable hello_message will be available at everywhere in the application.

Follow full example.

1) Create file called confi.json in the same level of the app.js:

{
    "SECRET": "Test",
    "KEY": "test.sid",
    "MAX_AGE": {
      "maxAge": 3600000
    }
  }

2) Alter the app.js for this:

var express = require('express')
  , cfg = require('./config.json')
  , load = require('express-load')
  , bodyParser = require('body-parser')
  , compression = require('compression')
  , methodOverride = require('method-override')
  , expressSession = require('express-session')
  , cookieParser = require('cookie-parser')
  , app = express()
  , cookie = cookieParser(cfg.SECRET);

app.use(compression());
app.use(cookie);

app.use(expressSession({
  secret: cfg.SECRET, 
  name: cfg.KEY, 
  resave: false, 
  saveUninitialized: false,

}));

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

app.get('/', function(req, res) {
  req.session.hello_message = "Hello world";
  console.log(req.session.hello_message);
});

app.listen(5000, function(){
  console.log("Test running");
});

module.exports = app;

3) Update the package.js:

{
  "name": "test",
  "version": "0.0.1",
  "description": "test",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "body-parser": "~1.12.0",
    "cookie-parser": "~1.3.4",
    "debug": "~2.1.1",
    "ejs": "~2.3.1",
    "express": "~4.12.2",
    "express-load": "1.1.8",
    "morgan": "~1.5.1",
    "serve-favicon": "~2.2.0"
  }
}

4) Run npm update --save for save the dependencies.

5) Open the browser: localhost:5000 and the message should appear in the console.

5 Comments

I tried but the problem persists, the session contains un object with the key "cookie" wich contains session params, path, _expires, sessionMaxAge ...
is req.session.hello_message accessible if i invoke another service, example if try to get /someService, will the value of session.hello_message be conserved ?
Yes, be conserved in the everywhere in the application. Try it!
Same problem, actually i have to services /validate and /import, the session is populated when the first one is invoked, the sceond one tries to retrieve data from session, but it's always empty.
If you can provide more information relevant (app.js content, route, controllers and etc)...
2

As noted in the answer to a related SO question, this can occur if you're using fetch to get data from your server but you don't pass in the credentials option:

fetch('/link2', {
    method: 'POST',
    credentials: 'same-origin' // <- this is mandatory to deal with cookies
})

Cookies won't be passed to the server unless you include this option.

1 Comment

This was such a mysterious error. Your answer saved my day. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.