【发布时间】:2014-12-05 07:48:30
【问题描述】:
来自 Passport 文档:
在典型的 Web 应用程序中,用于验证 用户只会在登录请求期间传输。如果 身份验证成功,将建立并维护一个会话 通过在用户浏览器中设置的 cookie。
每个后续请求都不会包含凭据,而是 标识会话的唯一 cookie。为了支持登录 会话,Passport 将序列化和反序列化用户实例以 并从会话中。
因此,由于身份验证在客户端的浏览器中维护,我应该能够将 Web 服务器扩展到 > 1(每个服务器使用相同的数据库)并让 Passport 从存储在 cookie 中的 ID 反序列化用户,无论是否服务器以前见过用户。如果服务器 之前见过用户,但不存在 cookie,我希望 Passport 无法通过身份验证...但我什至无法使用 n > 1 个服务器达到那么远。
使用 1 个服务器进程,Passport 工作正常:
服务器或多或少是两台服务器上的文档的逐字记录(经过多次尝试使用连接引用等):
app.configure(function() {
app.use(express.static('public'));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'keyboard cat' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
当用户登录成功时,在我返回 HTTP 请求之前,我记录了req.user 和req.session:
console.log(req.user);
console.log(req.session);
res.send(200, req.user);
// {"cookie":{
// "originalMaxAge":null,
// "expires":null,
// "httpOnly":true,
// "path":"/"
// },
// "passport":{"user":"ID"}}
当 HTTP 请求返回时,Web 应用程序请求 / 并期望服务器从传递的 cookie 中设置 req.user,ID 为 ID:
passport.deserializeUser(function(req, user_id, cb) {
console.info('Passport deserializing user: '
.concat(user_id));
console.log(req.user);
console.log(req.session);
// ...
// cb(null, user);
});
有 1 台服务器正在运行,这将记录为:
Passport deserializing user: ID
undefined
undefined
在回调cb(null, user) 之后和我返回请求之前,我立即记录req.user 和req.session,看看我会期待什么!
现在,n > 1 个服务器正在运行,假设是 2,如果 Web 应用从服务器 2 请求 / 并期望它从 cookie 中设置 ID 为 ID 的 req.user通过(最初通过登录服务器 1 设置),我什至没有看到调用的反序列化函数!当我将日志记录添加到 HTTP 路由的开头(在中间件之后):
console.log(req.user);
console.log(req.session);
我明白了:
undefined
// {"cookie":{
// "originalMaxAge":null,
// "expires":null,
// "httpOnly":true,
// "path":"/"
// },
// "passport":{}}
...这告诉我 cookie 出了点问题,但是什么?两个服务器进程都在同一个 DNS 后面的 Heroku 上。我已经阅读了关于为此需要一些“共享会话”存储的各种差异......但这就是客户端浏览器级别的cookie。请帮忙! Express 是最新的 3.X,Passport 是 2.1。
【问题讨论】:
标签: node.js cookies express connect passport.js