Sea*_*dre 6 session serialization prototype node.js express
所以我正在用 node.js、express、express-session 和 sequelize.js 构建一个网站。用户登录后,将User创建Sequelize 模型的实例。在我的用户登录 ( /auth/login)路线中,我有:
var user = (await User.findAll(
{where: {
username: username
}}))[0];
Run Code Online (Sandbox Code Playgroud)
我把它分配user给会话。
req.session.user = user;
Run Code Online (Sandbox Code Playgroud)
然后我可以通过简单地调用以下save方法来保留任何更改req.session.user:
await req.session.user.save();
Run Code Online (Sandbox Code Playgroud)
事实上,如果我接下来添加这一行:
console.log(Object.getPrototypeOf(req.session.user));
Run Code Online (Sandbox Code Playgroud)
输出是[object SequelizeInstance:User]。到现在为止还挺好。
在另一条路线 ( /users/myaccount/edit-bio) 中,我能够访问req.session.user. 也就是说,输出
console.log(req.session.user.username);
Run Code Online (Sandbox Code Playgroud)
是seanletendre,正如预期的那样。但是现在当我打电话
await req.session.user.save();
Run Code Online (Sandbox Code Playgroud)
我得到的只是错误消息:
UnhandledPromiseRejectionWarning: TypeError: req.session.user.save is not a function
Run Code Online (Sandbox Code Playgroud)
“这很奇怪,”我想,“这不是同一个物体吗?” 为了进行调查,我添加了以下行:
console.log(Object.getPrototypeOf(req.session.user));
Run Code Online (Sandbox Code Playgroud)
就像我在登录路径中所做的那样。输出是什么?它是:[object Object]。所以似乎不知何故原型req.session.user被遗忘了。我不明白这怎么可能。
是否可以将原型重新分配给普通对象?
根据对我的问题的评论,我怀疑当会话管理器序列化req.session. 似乎,与我之前的想法不同,对于不同的请求,req.session它并没有指向完全相同的session对象。每次请求结束时,它都会序列化并存储req.session. 然后在收到带有 cookie 的新请求时,将其指定为同一会话的一部分,session从会话存储中获取该对象。
这是我的会话中间件的设置方式:
var session = require('express-session');
//
// yada, yada, yada
//
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {secure: true}
}));
Run Code Online (Sandbox Code Playgroud)
所以令我惊讶的是,即使我使用的是默认 store MemoryStore,我的会话仍然是序列化的。
我现在的问题变成:如何在使用时防止会话存储上的对象序列化MemoryStore?
在express-session中,该方法save()由对象公开到对象(文档session)中,例如:request
req.session.save(callback)
Run Code Online (Sandbox Code Playgroud)
你的代码req.session.user.save()是错误的,正确的方法是req.session.save(),diff.:
req.session.user.save();
-----------^^^^^
req.session.save()
Run Code Online (Sandbox Code Playgroud)
该方法save()不是 a Promise,您必须传递回调以等待保存结果:
req.session.user = user;
req.session.save(function(err) {
if( err ){
// session not saved
} else {
// session saved
}
})
Run Code Online (Sandbox Code Playgroud)
您可以将其转换为 a Promise(并等待它),如下所示:
const saveSession = (req) => {
return new Promise((resolve, reject) => {
req.session.save(function(err) {
if( err ){
reject(err);
} else {
resolve(true);
}
});
});
};
req.session.user = user;
await saveSession(req);
Run Code Online (Sandbox Code Playgroud)
save()如果会话数据已更改,则会在 HTTP 响应结束时自动调用该方法。因此,通常不需要调用此方法。
更新
我调用 req.session.user.save() 因为我想将 Sequelize Model 实例保存到我的数据库中。
express-session 用于JSON.stringify()将会话序列化为字符串并存储到会话存储中(更多信息)。JSON.stringify()不理解函数,只存储属性。因此,你的save()功能就丧失了。
| 归档时间: |
|
| 查看次数: |
188 次 |
| 最近记录: |