我尝试这么做很多天但我的所有测试都失败了......
我平台上的用户使用passportjs策略(paypal,facebook,google ...)连接它们。
当用户连接时,我在标题的右侧写下他的昵称。 标题的html代码是从把手模板生成的,当这个部分由expressjs提供时,我将req.user会话对象发送到模板,以便写入昵称和其他信息......
顺便说一句,这很有用,但是当用户从他的个人资料中更新他的昵称时我遇到了问题,我无法在服务器端更新会话对象,如果用户重新加载页面,则会再次显示旧的昵称。
每次用户加载页面时我都不想从DB请求用户信息,所以我想保留这个配置:
// -- Passport session setup
passport.serializeUser(function(user, done) { done(null, user); });
passport.deserializeUser(function(obj, done) { done(null, obj); });
我设置本地的中间件:
// -- Set accessible datas from the template
res.locals = _.extend(res.locals, {
user: req.user,
query: req.url,
title: app.config.title,
url: app.config.url
});
我失败了:
// Trying to update req.user directly : not persistent
req.user.nickname = User.get('nickname');
// Trying to update passport session : exception error
req.session.passport.user = User.toJSON();
// Trying to replace full session object : not persistent
var session = req.session;
session.passport.user = User.toJSON();
req.session = session;
有什么建议吗?
暂时,只有退出然后登录才有效...这不是很有效:)
编辑:
// Application router
var Router = require('./helpers/router.js');
// Create Express Server
var app = express().http().io();
// -- Init app router
var router = new Router(app);
// -- Framework Middleware
app.use(router.middleware);
#########################
/***
* APP ROUTER
**/
// Export router
module.exports = function(app) {
// Set instance
var router = this;
// Returns routes register & middleware methods
return {
// -- Register routes
register: function() {
requirejs(['routes'], function(routes) {
_.each(routes, function(name, route) {
app.get(route, function(req, res, next) {
requirejs(['views/'+name], function(view) {
if ( view ) {
var _view = new view(_.extend(req.params, {server: {req: req, res: res, next: next}}));
_view.render(name, req, res, next);
}
else {
next();
}
}, function (err) {
console.log('error' + err)
});
});
});
});
},
// -- Bind middleware
middleware: function(req, res, next) {
// Get the current path
console.log("Middleware :: "+req.url);
// Add user informations
res.locals = _.extend(res.locals, {
user: req.user,
query: req.url,
title: app.config.title,
url: app.config.url
});
// Go next
next();
}
}
}
答案 0 :(得分:7)
这对我来说很有效:
req.session.passport.user.nickname = 'mynewnickname'
您是否在刷新之前对可能需要破坏的路线进行缓存?
(护照序列化是一样的)
passport.serializeUser(function(user, done) { done(null, user); });
passport.deserializeUser(function(obj, done) { done(null, obj); });
答案 1 :(得分:4)
我遇到了同样的问题,最后我找到了解决方案:
var user = newDataObj;
req.login(user, function(error) {
if (!error) {
console.log('succcessfully updated user');
}
});
res.end(); // important to update session
req.login将调用serialize函数并将新会话保存到db。 res.end()很重要。没有它,会话将不会被保存。
答案 2 :(得分:3)
对于' serializeUser'您将返回整个用户...这将序列化整个对象并将其放在用于跟踪会话的cookie中。该序列化仅发生一次(会话建立时)。当下一个请求进入时,它总是反序列化您最初存储的完全相同的用户对象,而您没有对其进行任何更新。这就是注销和重新登录的原因,因为它从数据库中检索已编辑的用户(我假设),并重新创建会话跟踪cookie。
要确认此答案,请在' serializeUser'上设置一个断点,并注意它只在您登录时才会被点击。
答案 3 :(得分:2)
这仍然是更新会议护照js'的最佳结果之一,所以我想我添加了对我有用的东西(提供的答案对我没用) :
req.session.passport.user.updatedfield= 'updatedvalue'
req.session.save(function(err) {console.log(err);}
如果没有req.session.save()
,会话数据就不会为我更新。
希望这有助于某人。
答案 4 :(得分:0)
Quan Duong的回答对我来说最有用,但这是一个更现实的情况:
async function foo(req, res) {
// get some data from somewhere
const newNickname = req.body.nickname;
// update the user database somehow - e.g. mongodb
const users = db.getCollection('users');
await users.updateOne({
_id: req.user._id
}, {
$set: {
nickname: newNickname
}
});
// create a temporary copy of the user w/ the updated property
const updatedUser = req.user;
updatedUser.nickname = newNickname
// persist the change to the session
req.login(updatedUser, async(error) => {
if (error) {
res.json({
err: 'Sorry, there was an error updating your account.'
});
return;
}
/*
maybe you need to call another function from here that uses the updated info before
responding to the original request
*/
try {
await bar(req.user);
} catch (error) {
res.json({
err: 'Sorry, there was an error updating your account.'
});
return;
}
// done
res.send(200);
});
}