2014-01-19 40 views
8

我见过这个问题的很多变体,但似乎没有解决我的问题。我正尝试使用Express设置Node.js服务器。这里是我的服务器配置:无法访问Express/NodeJS中的req.session变量

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会话正常工作?

+0

愚蠢的问题,但你贴实际上并不发送响应路由处理程序。你有没有尝试渲染或从'登录'重定向?虽然您的会话未存储在cookie中,但仍会在该过程中使用cookie。如果没有回应,那么这绝不会回到浏览器。 – juanpaco

+0

@juanpaco我实际上编辑了回复,但为了清晰起见,我将它们放回 –

回答

4

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

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

就您而言,您仅在/login请求中分配了req.session.user = user;。它不会提供进一步的请求(/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')); 
+0

这对我有用。谢谢。 – souravb

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