Nginx + node.js + express-session 竟然每次获取的session id不同/不一样.
有没有遇到这种情况,却怎么也查不出原因的?查完奔溃了,我去,这么简单?
用node.js的不同路由,竟然每次请求得到的session id不一样.
打开浏览器开发者模式吧, 查看一下第一个请求的[Response Headers], 发现没有Set-Cookie字段.
1. 于是开始搜索相关解决问题的方法,有的说跨域问题,于是解决了跨域,还是不行.
2. 有的说多进程直接存储在内存不能共享session id,可以使用redis,于是我又装了redis-server,然后在node.js里面使用redis,但还是不行.
上面不行之后查来查去都是这两种解决方法,真的无语,只能按部就班了,搞了一个正常的sample运行.然后对比差异.最终发现第一个请求的[Response Headers], 没有Set-Cookie字段.
下面是怎么解决?
最后发现是请求的时候没有使用req.session.
怎么使用呢?
看我的代码吧:
// this is my node_server.js
const http = require("http");
const cors = require("cors"); // 跨域, 应该不需要这个,加上吧,省的出问题
app.use(cors());
const cookieParser = require("cookie-parser"); // 应该不需要这个,加上吧,省的出问题
app.use(cookieParser());
const express = require("express");
const session = require("express-session");
const redis = require("redis"); //需要安装好redis-server,因为这个只是客户端
let RedisStore = require("connect-redis")(session);
let redisClient = redis.createClient(); // 看,这是客户端吧?
const bodyParser = require("body-parser"); //解析body的,不想要就别要了
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
const indexRouter = require("./node_routes/index.js"); // 我自己的index 路由文件, 处理放这个里面了
const host = "localhost";
const port = 3000;
const app = express();
app.set('trust proxy', 1);
app.use(session({
store: new RedisStore({
client: redisClient
}),
secret: 'guozongling',
saveUninitialized: false,
resave: false,
cookie: {maxAge: 60 * 1000 * 30}
}));
app.use('/*', indexRouter); // 使用我的index router
// 监听端口
const server = app.listen(port, function(req){
const host = server.address().address;
const port = server.address().port;
});
// this is my index.js file
const express = require("express");
const router = express.Router();
router.get('/', function(req, res, next) {
try {
console.log("GET -> "+req.session.id);
req.session.sign = true;
const path = req.path;
const url = req.url;
const originalurl = req.originalUrl;
const baseurl = req.baseUrl;
next();
} catch(error) {
res.end();
}
});
router.post('/', function(req, res, next) {
try {
console.log("POST -> "+req.session.id);
const path = req.path;
const url = req.url;
const originalurl = req.originalUrl;
const baseurl = req.baseUrl;
next();
} catch(error) {
res.end();
}
});
module.exports = router;
在 index.js文件中, router.get('/', function(req, res, next) { ... } 请求处理时使用req.session.sign,也就是使用了req.session,这样就会有 Set-Cookie字段, 那么接下来处理任何分发过来的请求session id都是一样了.
另外, 注意一下,app.use(session({
......
})); 这里的cookie设置,好像也有影响, 写成 cookie{ secure: true, path: '/', maxAge:60*1000*30}也会导致session id不同,还不知道为啥,这个对我来说也没用,就不管了.
比如处理:
GET /init
GET /videos
GET /query
等等
如果没有使用req.session,那么就没有Set-Cookie字段, 不同路由,甚至同一个路由也会改变session id.
希望对一些解决了跨域依旧没解决问题的人有帮助, 查看 [Set-Cookie]字段是线索,一切的起源.