简体   繁体   中英

Cannot access req.session variables in Express/NodeJS

I've seen many variations of this question, but none seemed to solve my issue. I'm trying to set up a Node.js server using Express . Here is my server configuration:

var express = require('express'),
    RedisStore = require('connect-redis')(express);

var app = express();

app.use(express.urlencoded());
app.use(express.json());
app.use(express.cookieParser());
app.use(express.session({
    store: new RedisStore(), 
    secret: APP_SECRET
}));

// Initialize redis connection
var client = redis.createClient();
client.on('connect', function() {
    console.log('Connected to Redis server')
})
client.on('error', function (err) {
    console.log('Error ' + err);
});

// Enable cross-origin resource sharing
app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With');
  next();
 });

var api = require('./controllers/api.js');

app.post('/login', api.login);
app.get('/auth', api.auth);

app.listen(3000);

And here are some simple routes:

exports.login = function(req, res) {
    var user = new User(req.username, req.password);
    req.session.user = user;
    console.log(req.session.user); //works
    res.json({user:user});
}

exports.auth = function(req, res) {
    console.log(req.session.user); //doesn't work
    res.json(req.session.user);
}

So in my login route, I can print the session variable as expected. But if I visit the auth route after visiting the login route, the session variable is undefined. How can I get Express sessions to work?

In a typical web application, the credentials used to authenticate a user will only be transmitted during the login request. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.

Each subsequent request will not contain credentials or all user data, but rather the unique cookie that identifies the session. In order to support login sessions, You have to serialize and deserialize user instances to and from the session in every request.

In your case, you have assigned req.session.user = user; only in /login request. It will not be available for further requests( /auth ).

You have to get user information in /auth request too by session id. (Or) Better you can use passport for authentication.

I think maybe your redis client is not connecting well, try something like this and be sure to start the redis service

sudo service redis-server start

or the way you are calling The RedisStore variable look at the example

example:

var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
var session = require('express-session');
var RedisStore = require('connect-redis')(session);

app.set('port',process.env.PORT || 3000);

app.use(cookieParser());
app.use(session({
    resave: true,
    saveUninitialized: true,
    store: new RedisStore({
      host: 'localhost',
      port: 6379
    }),
    secret: 'some string/hash secret'
}));


var counter=0;
app.get('/', function(request, response){
  //adding some value to request.session

   counter = counter+1;

  request.session.color = {'anyValue': counter};
  //
  console.log('Session ID: ', request.sessionID);
  console.log('Session: ', request.session);
  response.send('some text counter: '+request.session.color['anyValue']);

});


app.listen(app.get('port'));

The currently accepted answer didn't realize that express.session already handles cookie based sessions with the req.session object. I tried a trimmed down version of yours not using redis and it worked. Looking at the connect-redis docs it looks like you need to pass a session to connect-redis. You are currently passing it express. I believe changing that will fix your problem.

PS I would update your node/express versions as current versions of express no longer have the built in middleware along with other improvements.

Newer versions of express:

var session = require('express-session');
var cookieParser = require('cookie-parser');
var json = require('express-json');
var bodyParser = require('body-parser')

Rather than:

express.session
express.cookieParser
express.json
express.bodyParser

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM