我有一个简单的node.js服务器将connect-redis模块测试为会话存储。这一切都有效,但我注意到我得到了一个新的sess:在每个请求上键入redis。我只期望一个密钥,因为只有一个会话。
这是我的代码:
var connect = require('connect');
var util = require("util");
var RedisStore = require("connect-redis")(connect);
var http = require('http');
var app = connect()
.use(connect.cookieParser('keyboard cat'))
.use(connect.query())
.use(connect.session( {
secret:"elms",
store:new RedisStore({prefix:'sid_'}),
cookie:{maxAge:60000, secure:false}
}))
.use(function(req, res, next) {
var sess = req.session;
if (sess.views) {
res.setHeader('Content-Type', 'text/html');
res.write("<p>" + util.inspect(req.cookies) + "</p>");
sess.basket = sess.basket || {book1:0, book2:0, book3:0};
if(req.query.buyBook1) {sess.basket.book1 ++;}
if(req.query.buyBook2) {sess.basket.book2 ++;}
if(req.query.buyBook3) {sess.basket.book3 ++;}
if(req.query.expiresession) {
sess.cookie.maxAge = 0;
}
res.write('<p>views: ' + sess.views + '</p>');
res.write('<ul>\
<li>book1 ' + sess.basket.book1 + ' - <a href="/?buyBook1=true">Add</a></li>\
<li>book2 ' + sess.basket.book2 + ' - <a href="/?buyBook2=true">Add</a></li>\
<li>book3 ' + sess.basket.book3 + ' - <a href="/?buyBook3=true">Add</a></li>\
</ul>\
<a href="/?expiresession=true">Expire session</a>');
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
res.write('<p>path: ' + sess.cookie.path + '</p>');
res.write('<p>domain: ' + sess.cookie.domain + '</p>');
res.write('<p>secure: ' + sess.cookie.secure + '</p>');
sess.views ++;
} else {
sess.views = 1;
}
res.write("<p>" + util.inspect(req.cookies) + "</p>");
res.end('welcome to the session demo. refresh!');
});
http.createServer(app).listen(3000);
我注意到req.session.cookie.domain始终为null。我在Windows 8上并使用hosts文件将127.0.0.1映射到www.gaz-node.com,这就是我在服务器上使用的cookie域。可能是相关的。
有什么想法吗? 感谢
答案 0 :(得分:7)
答案很简单。我在这个星期天早上特别早起,为了调试它,在我的第一杯咖啡中间突然清楚答案,后来品尝的咖啡比上半年更好。
/favicon.ico请求的复仇
我没有处理来自浏览器的/favicon.ico请求,这对像我这样的节点新手来说是个问题。每个请求后面都有一个/favicon.ico请求(至少是Chrome),因此浏览器可以显示该网站的图标。它永远不会放弃,直到它得到一个favicon.ico。
实际会话运行得非常好,只有一个会话ID,但是/favicon.ico的请求没有发送任何cookie,而且这是每个请求都触发一个新的僵尸会话。
为了解决这个问题,我添加了一个模块来处理/favicon.ico请求并提供404响应。我可以很容易地给无情的浏览器一个favicon并使用“fs”模块发送它。
在使用会话模块之前,在不调用next()的情况下处理/favicon.ico并结束响应非常重要!这是固定代码:
var connect = require('connect');
var util = require("util");
var RedisStore = require("connect-redis")(connect);
var http = require('http');
var app = connect()
.use(function(req, res, next) {
if(req.url == '/favicon.ico') {
serve404(res);
} else {
next();
}
})
.use(connect.cookieParser())//"elms123"))
.use(connect.query())
.use(connect.session( {
secret:"elms123",
store:new RedisStore({prefix:'sid_'}),
cookie:{maxAge:60000, secure:false, domain:"gaz-node.com"}
}))
.use(function(req, res, next) {
var sess = req.session;
res.setHeader('Content-Type', 'text/html');
res.write('welcome to the session demo. refresh!');
if (sess.views) {
res.write("<p>" + util.inspect(req.cookies) + "</p>");
sess.basket = sess.basket || {book1:0, book2:0, book3:0};
if(req.query.buyBook1) {sess.basket.book1 ++;}
if(req.query.buyBook2) {sess.basket.book2 ++;}
if(req.query.buyBook3) {sess.basket.book3 ++;}
if(req.query.expiresession) {sess.cookie.maxAge=0;}
if(req.query.forceerror) {/*idontexist()*/throw new Error('ahhhh!');}
res.write('<p>views: ' + sess.views + '</p>');
res.write('<ul>\
<li>book1 ' + sess.basket.book1 + ' - <a href="/?buyBook1=true">Add</a></li>\
<li>book2 ' + sess.basket.book2 + ' - <a href="/?buyBook2=true">Add</a></li>\
<li>book3 ' + sess.basket.book3 + ' - <a href="/?buyBook3=true">Add</a></li>\
</ul>\
<a href="/?expiresession=true">Expire session</a>\
<a href="/?forceerror=true">Force error</a>');
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
res.write('<p>path: ' + sess.cookie.path + '</p>');
res.write('<p>domain: ' + sess.cookie.domain + '</p>');
res.write('<p>secure: ' + sess.cookie.secure + '</p>');
sess.views ++;
} else {
sess.views = 1;
}
res.end("<p>" + util.inspect(req.cookies) + "</p>");
})
.use(connect.errorHandler());
http.createServer(app).listen(3000);
function serve404(res) {
res.writeHead(404, {"content-type": "text/plain"});
res.end("Error : Resource not found");
}
答案 1 :(得分:0)
我也遇到过这个问题。当然,我们应该使用'favicon'中间件。并确保将“会话”中间件置于“静态”下方。请参阅我的回答https://stackoverflow.com/a/21094838/3190612