ваш 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 : для проверки пользователя имеетподтвержденный адрес электронной почты или нет
провайдер : зарегистрировать провайдера, например, facebook, google..etc ... по умолчанию используется адрес электронной почты, если пользователь зарегистрировался с помощью электронной почты.
provider_id : идентификатор провайдера - это уникальный идентификатор пользователя, предоставленный социальными сетями (Facebook, Google)
password_reset_token : случайная строка токена, когда пользователь забыл пароль и отправил этот токен по электронной почте для сброса пароля
Теперь, когда пользователь регистрируется по электронной почте, сохраните пароль, введенный пользователем.
при регистрации пользователя через провайдера социальных сетей (facebook, google) .. затем сгенерируйте случайную строку, создайте пароль с помощью bcrypt и сохраните в поле пароля,помните: поле пароля не может быть пустым для пользователей, которые регистрируются с помощью социальных сетей,
теперь создайте файл 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
и генерирует токен randon и задает verify_token:'random token'
при создании пользователя, а затем отправляет письмо с подтверждением учетной записи, используя NodeMailer с этим случайным токеном ссылка для проверки
создает новый маршрут для обработки проверки электронной почты, например /verify
, когда пользователь нажимает на ссылку из электронного письма, этот маршрут будет обрабатывать запрос, найти пользователя по verify_token и установить email_verified : true
, если токенправильно, иначе покажите ошибку.
Надеюсь, мой ответ поможет вам:)