【问题标题】:connect-redis and express-session results in req.session undefinedconnect-redis 和 express-session 导致 req.session 未定义
【发布时间】:2014-12-29 17:13:42
【问题描述】:

我正在尝试让 express-session 将会话存储在 Redis 中,但它似乎不想保存。当我恢复到默认会话存储时,它可以完美运行。 Redis 守护程序托管在具有默认配置的 Vagrant VM 上,应用程序能够连接到它,尽管它不想保存会话。

这是我的代码:

var express = require('express');
var glob = require('glob');

var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var compress = require('compression');
var methodOverride = require('method-override');
var session = require('express-session');
var passport = require('passport');
var redis = require('redis');
var RedisStore = require('connect-redis')(session);
var auth = require('./passport');
var flash = require('connect-flash');

module.exports = function(app, config) {
  app.set('views', config.root + '/app/views');
  app.set('view engine', 'jade');

  // app.use(favicon(config.root + '/public/img/favicon.ico'));
  app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({
    extended: true
  }));
  app.use(cookieParser());
  app.use(session({ 
    store: new RedisStore({ 
      host: config.redis.host,
      port: config.redis.port
    }),
    secret: config.secret, 
    saveUninitialized: true,
    resave: false 
  }));
  /*app.use(session({
    secret: config.secret,
    saveUninitialized: true,
    resave: true
  }));*/
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(flash());
  app.use(compress());
  app.use(express.static(config.root + '/public'));
  app.use(methodOverride());

  var controllers = glob.sync(config.root + '/app/controllers/*.js');
  controllers.forEach(function (controller) {
    require(controller)(app);
  });

  app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
  });

  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,
        title: 'error'
      });
    });
  }

  app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: {},
      title: 'error'
    });
  });

};

如您所见,我将默认的注释掉了,如果我删除了这些 cmets 并注释掉了 redis 存储,它就可以正常工作。任何线索为什么会发生这种情况?我没有收到任何错误。

【问题讨论】:

    标签: node.js session express node-redis


    【解决方案1】:

    您可能有一些连接错误,但connect-redis 不会将它们输出到控制台(请参阅connect-redis source code)。要查看它们,您可以创建一个单独的模块来创建客户端实例并将其传递给 RedisStore 构造函数:

    // redisClient.js
    var redis = require('redis');
    
    var redisClient = redis.createClient('localhost', 6379); // replace with your config
    
    redisClient.on('error', function(err) {
         console.log('Redis error: ' + err);
    }); 
    
    module.exports = redisClient;
    

    Redis 客户端还会发出其他可能有助于调试的事件 - 请参阅 node-redis docs

    // your code
    var redisClient = require('./redisClient.js`);
    
    (...)
    
    app.use(session({ 
        store: new RedisStore({ 
            client: redisClient
        }),
        secret: config.secret, 
        saveUninitialized: true,
        resave: false 
    }));
    

    【讨论】:

    • 我之前曾尝试使用您在此处提供的完全相同的代码创建一个单独的客户端实例,但无济于事。还有其他线索吗?谢谢!
    • 能否为 redisClient 发出的其他事件(如'ready'、'connect'或'end')添加监听器以查看连接是否实际建立?
    • 我现在开始工作了,遇到了 ECONNRESET 错误。 Vagrant VM 还配备了另一台 Redis 服务器......但不起作用的一件事是 app.use(flash()); 行。当我尝试访问 Passport 发送的req.flash('error'); 时,它是空的。它适用于默认的快速会话存储,但由于某种原因不适用于 Redis。
    • 根据github.com/NodeRedis/node_redis#rediscreateclient,应该是redis.createClient(6379, 'localhost')
    猜你喜欢
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 2014-04-24
    • 2014-03-05
    • 1970-01-01
    • 2016-04-01
    相关资源
    最近更新 更多