无法访问Express / NodeJS中的req.session变量

时间:2014-01-19 03:25:08

标签: javascript node.js session express

我已经看到了这个问题的很多变化,但似乎都没有解决我的问题。我正在尝试使用Node.js设置Express服务器。这是我的服务器配置:

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);

以下是一些简单的路线:

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);
}

所以在我的login路由中,我可以按预期打印会话变量。但是,如果我在访问auth路由后访问login路由,则会话变量未定义。如何让Express会话发挥作用?

3 个答案:

答案 0 :(得分:4)

在典型的Web应用程序中,用于验证用户的凭据只会在登录请求期间传输。如果验证成功,将通过用户浏览器中设置的cookie建立和维护会话。

每个后续请求都不会包含凭据或所有用户数据,而是包含标识会话的唯一Cookie。为了支持登录会话,您必须在每个请求中对会话进行序列化和反序列化。

在您的情况下,您仅在req.session.user = user;请求中指定了/login。它不能用于进一步的请求(/auth)。

您必须通过会话ID在/auth请求中获取用户信息。 (或者)最好使用passport进行身份验证。

答案 1 :(得分:1)

我想也许你的redis客户端连接不好,试试这样的东西并确保启动redis服务

sudo service redis-server start

或您调用RedisStore变量的方式查看示例

示例:

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'));

答案 2 :(得分:1)

当前接受的答案没有意识到express.session已经使用req.session对象处理基于cookie的会话。我尝试了一个不使用redis的你的剪裁版本,它工作。查看connect-redis文档,看起来您需要将会话传递给connect-redis。您目前正在通过快递。我相信改变这将解决你的问题。

P.S。我会更新您的节点/快速版本,因为当前版本的express不再具有内置中间件以及其他改进。

快递的新版本:

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

而不是:

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