Node.js 无法使MongoDB存储区使用PassportJS
我是Node.JS和Express的初学者,但我已经成功创建了一个功能齐全的web应用程序。我注意到,在进入生产模式时,我将会话存储在RAM中。相反,我想把它们存放在Mongo商店 因为我使用的是Passport,所以我想知道如何获得序列化和反序列化函数来使用Mongo商店。存储会话似乎效果不错(我在数据库中看到了它),但我无法获取它 更准确地说,我想知道如何检索会话ID以从数据库中获取用户。 这是我的服务器代码:Node.js 无法使MongoDB存储区使用PassportJS,node.js,mongodb,express,mongoose,passport.js,Node.js,Mongodb,Express,Mongoose,Passport.js,我是Node.JS和Express的初学者,但我已经成功创建了一个功能齐全的web应用程序。我注意到,在进入生产模式时,我将会话存储在RAM中。相反,我想把它们存放在Mongo商店 因为我使用的是Passport,所以我想知道如何获得序列化和反序列化函数来使用Mongo商店。存储会话似乎效果不错(我在数据库中看到了它),但我无法获取它 更准确地说,我想知道如何检索会话ID以从数据库中获取用户。 这是我的服务器代码: var store = new MongoDBStore( {
var store = new MongoDBStore(
{
uri: process.env.MONGODB_URI,
mongooseConnection: db,
collection: 'mySessions'
});
// Catch errors
store.on('error', function(error) {
throw error;
});
app.use(session({
secret: '****',
resave: true,
store: store,
saveUninitialized: true,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000}
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT,
clientSecret: process.env.GOOGLE_SECRET,
callbackURL: process.env.CALLBACK_URL
},
function(accessToken, refreshToken, profile, done) {
var user = new User();
var profileUser = user.extractProfile(profile);
done(null, profileUser.email); // The only info I need is the user email address
}
));
passport.serializeUser(function(user, done) {
console.log('Serializing user:'+user); // user returns the email address
done(null, user); // The session is stored
});
var Sessions = db.collection('mySessions');
passport.deserializeUser(function (id, done) {
console.log('Deserializing user:'+id); // What clearly doesn't work here, is that I'm trying to fetch a document using the email address instead of the "_id"...
return Sessions.findOne({ user: id }, function (error, user) {
console.log('Found :');
console.log(user);
return done(error, user);
});
});
以下是Mongo商店中的一个条目:
{
"_id": "10yEo3rU4Qumf2jw3346UtY0cCnRWNhc",
"session": {
"cookie": {
"originalMaxAge": 604800000,
"expires": {
"$date": "2017-02-25T13:46:57.231Z"
},
"secure": null,
"httpOnly": true,
"domain": null,
"path": "/",
"sameSite": null
},
"passport": {
"user": "le*****@*****.com"
}
},
"expires": {
"$date": "2017-02-25T13:46:57.231Z"
}
}
我相信,如果我能够使反序列化功能正常工作,一切都会像以前一样工作。有什么办法吗
(编辑)我编辑了反序列化函数,对我的会话ID进行手动搜索(我从Mondo数据库获得了ID),如下所示:
passport.deserializeUser(function (id, done) {
console.log('Deserializing user:'+id);
return Sessions.findOne({ _id: 'faogaErvZirU2lVpo49M-Bkz7zuQwbhP' }, function (error, user) {
console.log('Found :');
console.log(user);
return done(error, user.session.passport.user);
});
});
它是有效的。所以,除非我弄错了,否则我唯一需要弄清楚的是如何从饼干中获取_id,对吗
谢谢大家! 在几个小时寻找答案后,我检查了GitHub上的类似项目,更准确地说,是Passport与存储会话的成功集成 我发现了我的问题:我需要存储我的用户,而不是他们的会话(Mongo商店已经在这样做了)。因此,我改变了谷歌的策略,在数据库中创建新用户或检索其配置文件:
var UserDB = db.collection('users');
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT,
clientSecret: process.env.GOOGLE_SECRET,
callbackURL: process.env.CALLBACK_URL,
},
function(token, refreshToken, profile, done) {
process.nextTick(function() {
UserDB.findOne({ 'id': profile.id }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, user);
} else {
var newUser = {};
newUser.id = profile.id;
newUser.token = token;
newUser.name = profile.displayName;
newUser.email = profile.emails[0].value;
UserDB.insert({ 'id': profile.id, 'token': token, 'name': profile.displayName , 'email': profile.emails[0].value}, function (err) {
if (err) {
throw err;
}
return done(null, newUser);
});
}
});
});
}));
从那以后,我只需在数据库中查找用户:
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function (user, done) {
return UserDB.findOne({ id: user.id }, function (error, user) {
return done(error, user);
});
});
我的错误是认为serializeUser和deserializeUser都是关于会话的,而实际上都是关于用户配置文件的。会话由Express session和MongoDB Store 100%管理,所以我不必担心它们