2014-01-19 68 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