Passport.js-使用本地护照从MongoDB验证用户 [英] passport.js - authenticate users from MongoDB with passport-local
问题描述
我的MongoDB中有一个简单的用户集合.我使用mongo-native驱动程序.
I have a simple users collection in my MongoDB. I user mongo-native driver.
{
"email": "johndow@example.com",
"password": "123456",
"_id": {
"$oid": "50658c835b821298d3000001"
}
}
当我通过对email:pass进行用户身份验证时,我将默认的本地护照功能findByUsername重新编写为:
As I user auth via pair email:pass, I re-wrote default passport-local function findByUsername to this:
function findByEmail(email, fn) {
db.collection("users", function(err, collection) {
collection.find({}, {}, function(err, users) {
users.each(function(err, user) {
if (user.email === email) {
return fn(null, user);
}
});
return fn(null, null);
});
});
}
只需从DB中获取所有用户,然后检查-如果user.email ==提供了电子邮件,则返回用户对象.
Just get all of the users form DB, and checking - if user.email == provided email, then return user object.
我将MongoDB的_id参数用作用户的ID,这就是为什么我修改了这两个函数的原因:
I use _id parameter of MongoDB as id for users, that's why I've modifies these two functions:
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
findById(id, function(err, user) {
done(err, user);
});
});
这是我的护照本地策略代码:
And this is my code for passport local strategy:
passport.use(new LocalStrategy( function(email, password, done) {
process.nextTick(function() {
console.log('initialize findByEmail() for "',email,'"');
findByEmail(email, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
console.log('Unknown user ' + email)
return done(null, false, {
message: 'Unknown user ' + email
});
}
if (user.password != password) {
console.log('Invalid password')
return done(null, false, {
message: 'Invalid password'
});
}
//сonsole.log('ALL VERIFIATION PASSED');
return done(null, user);
})
});
}));
我从登录页面发布数据:
I post data from login page:
app.post('/login', passport.authenticate('local', {
failureRedirect: '/',
failureFlash: true
}), function(req, res) {
res.redirect('/desk');
});
我明白了
Error: Can't set headers after they are sent.
然后我得到
TypeError: Cannot read property 'email' of null
最后一个错误确实很奇怪,因为findByEmail具有console.log(user)行(从此清单中删除),并且列出了所有用户数据.
The last error is really strange 'cause findByEmail has console.log(user) line (removed from this listing) and it list all the user's data.
我在做什么错了?
推荐答案
虽然没有充分的文档说明,但cursor.each
为其回调的第二个参数提供了null
值,以指示光标没有更多可用的文档.仅在文档的示例中提到
It's not well documented, but cursor.each
provides a null
value to the second parameter of its callback to indicate that the cursor has no more documents available. It's only mentioned in the example of the documentation.
因此,在您的情况下,您应该在users.each
回调中检查user !== null
.
So in your case you should be checking for user !== null
in your users.each
callback.
但是,让mongo通过将find
调用更改为:
However, it would be more efficient to have mongo do the searching for you by changing your find
call to:
collection.findOne({email: email}, {}, function(err, user) {
if (user) {
// email was found case
...
}
...
}
这篇关于Passport.js-使用本地护照从MongoDB验证用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!