你的User schema应该是:
const mongoose = require('mongoose')
var Schema=mongoose.Schema;
var bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
fullName: {type:String,required:true,default:''},
email: {type:String,required:true,unique:true},
email_verified:{type:Boolean,default:false},
verify_token:{type:String,default:null},
provider:{type:String,default:'email'},
provider_id:{type:String,default:null},
password: {type:String},
password_reset_token:{type:String,default:null},
image: {type:String,default:null},
created_at:{type:Date,default:Date.now},
updated_at:{type:Date,default:Date.now},
},{
collection:'User'
});
module.exports = mongoose.model('User', userSchema);
module.exports.encryptPassword=function(password)
{
var salt= bcrypt.genSaltSync(10);
var hash= bcrypt.hashSync(password,salt,null);
return hash;
}
module.exports.validPassword=function(password,hash){
return bcrypt.compareSync(password,hash);
}
这里添加了一些额外的有用字段:
email_verified:用于检查用户是否已验证电子邮件
provider :注册提供者,如 facebook 、 google..etc ...默认
如果用户使用电子邮件注册,则为电子邮件。
provider_id:提供者 id 是社交提供的用户的唯一 id
媒体(Facebook、谷歌)
password_reset_token:是随机令牌字符串,当用户忘记密码并通过电子邮件发送此令牌以重置密码时
现在创建文件passport.js:
var FacebookStrategy = require('passport-facebook').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var User = require('../models/user');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID : 'clientID',
clientSecret : 'clientSecret',
callbackURL : 'callbackURL'
},
// facebook will send back the token and profile
function(token, refreshToken, profile, done) {
console.log("TOKEN = "+token);
console.log("REFRESH TOKEN = "+refreshToken);
console.log("PROFILE = "+JSON.stringify(profile));
// find the user in the database based on their facebook id
User.findOne({ 'provider_id' : profile.id }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, user); // user found, return that user
} else {
console.log(profile);
let randomString= Math.random().toString(36).substring(2);
var newUser = new User({
fullName : profile.displayName,
email :profile.emails[0].value,
email_verified : true,
password : User.encryptPassword(randomString),
image : 'get user image from response',
provider : 'facebook',
provider_id : profile.id,
});
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
}));
passport.use(new GoogleStrategy({
clientID : 'clientID',
clientSecret : 'clientSecret',
callbackURL : 'callbackURL',
},
function(token, refreshToken, profile, done) {
User.findOne({ 'provider_id' : profile.id }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, user);
} else {
let randomString= Math.random().toString(36).substring(2);
var newUser = new User({
fullName : profile.displayName,
email :profile.emails[0].value,
email_verified : true,
password : User.encryptPassword(randomString),
image : 'get user image from response',
provider : 'google',
provider_id : profile.id,
});
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
}));
}
额外的注意事项:当用户使用 facebook/google 注册时,设置email_verified:true,因为用户已经通过提供商验证了他的电子邮件,
当用户使用他的电子邮件集email_verified:false注册并生成随机令牌并在创建用户时设置verify_token:'random token',然后使用带有此随机令牌的NodeMailer发送帐户验证电子邮件,验证链接
生成处理邮件验证的新路由,如/verify,当用户从邮件中点击链接时,该路由将处理请求,通过verify_token查找用户并设置email_verified : true,如果令牌正确则显示错误。
希望我的回答能帮到你:)