【问题标题】:Cannot access req.session variables in Express/NodeJS无法访问 Express/NodeJS 中的 req.session 变量
【发布时间】:2014-02-08 08:57:11
【问题描述】:

我见过这个问题的许多变体,但似乎没有一个能解决我的问题。我正在尝试使用Express 设置Node.js 服务器。这是我的服务器配置:

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 路由中,我可以按预期打印会话变量。但是如果我在访问login 路由后访问auth 路由,会话变量是未定义的。如何让 Express 会话正常工作?

【问题讨论】:

  • 愚蠢的问题,但您发布的路由处理程序实际上并没有发送响应。您是否尝试过从login 进行渲染或重定向?虽然您的会话未存储在 cookie 中,但在此过程中仍会使用 cookie。如果没有响应,则永远不会返回浏览器。
  • @juanpaco 我实际上编辑了回复,但为了清楚起见,我会把它们放回去

标签: javascript node.js session express


【解决方案1】:

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

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

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

您也必须通过会话 ID 在/auth 请求中获取用户信息。 (或)更好的是你可以使用passport 进行身份验证。

【讨论】:

  • 好的,我需要一个更详细的解释或者一个例子。
【解决方案2】:

我想可能是你的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'));

【讨论】:

    【解决方案3】:

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

    附:我会更新您的 node/express 版本,因为当前版本的 express 不再具有内置中间件以及其他改进。

    较新版本的 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
    

    【讨论】:

      猜你喜欢
      • 2012-11-19
      • 2014-04-24
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 2021-05-27
      • 2020-06-11
      相关资源
      最近更新 更多