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.

khalil
  • 681
  • 1
  • 6
  • 22
  • The solution is to allow credentials in the angular app, [link](http://stackoverflow.com/questions/17064791/http-doesnt-send-cookie-in-requests) – khalil Sep 14 '15 at 10:09

3 Answers3

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

Community
  • 1
  • 1
khalil
  • 681
  • 1
  • 6
  • 22
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.

BrTkCa
  • 4,703
  • 3
  • 24
  • 45
  • I tried but the problem persists, the session contains un object with the key "cookie" wich contains session params, path, _expires, sessionMaxAge ... – khalil Sep 11 '15 at 13:45
  • 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 ? – khalil Sep 11 '15 at 14:45
  • Yes, be conserved in the everywhere in the application. Try it! – BrTkCa Sep 11 '15 at 14:47
  • 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. – khalil Sep 11 '15 at 14:54
  • If you can provide more information relevant (app.js content, route, controllers and etc)... – BrTkCa Sep 11 '15 at 14:58
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.

Community
  • 1
  • 1
Chase Sandmann
  • 4,795
  • 3
  • 30
  • 42