правильный способ использования местного паспорта с паспортом facebook / google - PullRequest
0 голосов
/ 24 декабря 2018

Так что я размышлял над этим в течение некоторого времени.

Я использую passport-local для тех, кто не хочет регистрироваться, используя facebook / google, и passport-google и facebook для тех, кто предпочитает быструю регистрацию, используя социальные логины.

Так как, это мое первое приложение, я не могу разобраться с Как Я могу использовать оба из них вместе.

Например, я создаю схему для хранения пользовательских данных

const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
    fullName: String,
    email: String,
    passowrd: String, 
    image: String
}) 


module.exports = mongoose.model('User', userSchema);

Схема имеет поле пароля.Теперь Social Login не будет отправлять пароль пользователя, но для локального входа нам потребуется пароль.

Единственный вариант, который я могу придумать, - это создать две схемы: одну с паролем и одну без пароля.

Вопрос: Это то, что люди обычно делают?похоже, что лучший подход для продолжения или кто-то может предложить мне лучшую альтернативу

1 Ответ

0 голосов
/ 24 декабря 2018

ваш 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, если токенправильно, иначе покажите ошибку.

Надеюсь, мой ответ поможет вам:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...