下面是我工作的,解決方案是基於一個基於貓鼬的odm,第一部分是護照相關部分,我也附加了odm的用戶部分,以及如何對密碼進行加密。
如果我理解你的問題,你希望用戶輸入他的電子郵件或密碼。在這種情況下,修改搜索以嘗試兩種方式,即匹配提供的用戶標識符(在您撥打findOne(...)時用用戶名或密碼。
請注意,我使用bcrypt來避免存儲明確的密碼,這就是爲什麼有一個用於測試密碼的自定義比較方法,還要注意使用谷歌身份驗證的'提示',我的系統啓用了兩個,如果有關的話,請讓我知道,我可以添加所需的代碼
------------驗證部(只是相關片段)-----------
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user, done) {
// the values returned here will be used to deserializeUser
// this can be use for further logins
done(null, {username: user.username, _id: user.id, role: user.role});
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(new LocalStrategy(function(username, password, done){
odm.User.findOne({username: username, authType: 'direct'}, function(err, user){
if(err){
return done(err, false);
}
if(!user){
return done(null, false);
}
if(user.role === 'new'){
console.log('can not use new user!');
return done('user not activated yet, please contact admin', false);
}
user.comparePassword(password,function(err, isMatch){
if(err){
return done(err, false);
}
if(isMatch){
return done(null, user);//{username: username});
}
return done(null, false);
});
});
}));
app.post('/login', function(req, res, next){
passport.authenticate('local', {
failureRedirect: '/logout?status=login failed'
}, function(err, user, info){
if(err){
return next(err);
}
if(!user){
return res.redirect('/login');
}
req.logIn(user, function(err){
if (req.body.rememberme) {
req.session.cookie.maxAge = 30*24*60*60*1000 ;//Rememeber 'me' for 30 days
} else {
req.session.cookie.expires = false;
}
var redirect = req.param('redirect') || '/index';
res.redirect(redirect);
});
}
)(req, res, next);
}
);
app.post('/register',function(req, res){
var user = new odm.User({username: req.body.username, password: req.body.password, email: req.body.email, authType: 'direct'});
user.save(function(err, user){
if(err){
console.log('registration err: ' , err);
} else {
res.redirect('/list');
}
});
});
---用戶/ ODM,相關部分---- ------------
var bcrypt = require('bcrypt-nodejs');
// --------------------- User ------------------------------------------ //
var userSchema = new Schema({
name: String,
email: String,
username: {type: String, required: true, unique: true},
password: String,
role: {type: String, required: true, enum: ['new', 'admin', 'user'], default: 'new'},
authType: {type: String, enum: ['google', 'direct'], required: true}
});
userSchema.pre('save', function (next) {
var user = this;
if (!user.isModified('password')) return next();
console.log('making hash...........');
bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, null, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
userSchema.methods.comparePassword = function (candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
爲什麼downvote? – Forivin
你可能不得不建立自己的策略,但是你可以很容易地找到已經構建的策略,例如https:// github。com/zkochan/passport-email – mfreitas
密碼已過時,您基本上要求用戶在您的網站上記住互聯網上的第100個密碼,並且他們在第二次訪問您的網站時忘記了密碼,關於passportjs或任何快遞auth中間件使用非常相同的策略電子郵件/密碼或名稱/密碼,您將編寫更多臃腫的代碼來處理登錄/ err登錄/忘記密碼api。無論是使用FB /谷歌auth api或者你可以使用https://github.com/florianheinemann/passwordless – syarul