2016-12-09 6 views
1

Я пытаюсь настроить аутентификацию пользователя с помощью паспортаJS. Я решил использовать этот пакет npm под названием mongoose-findorcreate вместо написания функции findOrCreate для работы с паспортом самостоятельно.mongoose-findorcreate, пишущий дублированных пользователей при использовании паспорт-facebook

Итак, теперь я тестирую свое приложение, и я могу войти в систему, используя мои учетные данные в facebook, как ожидается, но проблема в том, что я получаю несколько записей в моей базе данных для того же входа в facebook.

Это моя модель пользователя:

let mongoose = require('mongoose'); 
let Schema = mongoose.Schema; 

let findOrCreate = require('mongoose-findorcreate'); 

// User schema definition 
let UserSchema = new Schema(
    { 
    provider: { type: String, required: true }, 
    id: { type: String, default: 'unknown' }, 
    displayName: { type: String, default: 'unknown' }, 
    name: { type: Object }, 
    emails: { type: Array }, 
    photos: { type: Array }, 
    createdAt: { type: Date, default: Date.now }, 
    updatedAt: { type: Date, default: Date.now }, 
    } 
); 

UserSchema.plugin(findOrCreate); 

// Sets the updatedAt parameter equal to the current time 
UserSchema.pre('save', (next) => { 
    now = new Date(); 
    if(!this.updatedAt) { 
    this.updatedAt = now; 
    } 
    next(); 
}); 

module.exports = mongoose.model('user', UserSchema); 

Это мои маршруты:

let passport = require('passport'); 
let FacebookStrategy = require('passport-facebook').Strategy; 

let User = require('../models/user'); 

passport.use(new FacebookStrategy({ 
    clientID: 12345, 
    clientSecret: 'supersecretsecret', 
    callbackURL: 'http://localhost:1337/auth/facebook/callback' 
    }, 
    (accessToken, refreshToken, profile, done) => { 
    User.findOrCreate(profile, (err, user) => { 
     if (err) { 
     return done(err); 
     } 
     done(null, user); 
    }) 
    } 
)); 

passport.serializeUser(function(user, done) { 
    done(null, user.id); 
}); 

passport.deserializeUser(function(id, done) { 
    User.findById(id, function(err, user) { 
    done(err, user); 
    }); 
}); 

function redirectFB() { 
    return passport.authenticate('facebook'); 
} 

function callbackFB() { 
    return passport.authenticate('facebook', { 
    successRedirect: '/word', 
    failureRedirect: '/' 
    }) 
} 

module.exports = { redirectFB, callbackFB }; 

Пример дублированных пользователей:

{ 
    "_id":ObjectId("584ade8915644f1186fa8a96"), 
    "provider":"facebook", 
    "updatedAt": ISODate("2016-12-09T16:40:41.921 Z"), 
    "createdAt": ISODate("2016-12-09T16:40:41.921 Z"), 
    "photos":[ ], 
    "emails":[ ], 
    "displayName":"Miha Šušteršič", 
    "id":"10154914634234238", 
    "__v":0 
}{ 
    "_id":ObjectId("584adea3b8adfb11948ed1d6"), 
    "provider":"facebook", 
    "updatedAt": ISODate("2016-12-09T16:41:07.626 Z"), 
    "createdAt": ISODate("2016-12-09T16:41:07.625 Z"), 
    "photos":[ ], 
    "emails":[ ], 
    "displayName":"Miha Šušteršič", 
    "id":"10154914634234238", 
    "__v":0 
} 

Я не могу понять, если это проблема с моим кодом (передача профиля функции findOrCreate или нет).

ответ

1

Причина findOrCreate не будет работать, потому что findOrCreate запрос проходит весь profile объект в критерии запроса.

Если вы посмотрите здесь: https://github.com/drudge/mongoose-findorcreate/blob/master/index.js#L22

В зависимости от того, какого типа данных вы получите обратно от Facebook, ваш запрос всегда будет возвращать пустым, если объект профиля не соответствует вашей схеме ТОЧНО.

Что вы можете сделать здесь заключается в следующем:

User.findOrCreate({ provider: profile.provider, id: profile.id, .... }, (err, user) => { 
    if (err) { 
    return done(err); 
    } 
    done(null, user); 
}) 

вместо profile проходят в { provider: profile.provider, id: profile.id, .... }

конечно, зафиксировать { provider: profile.provider, id: profile.id, .... } быть согласованы с определением схемы.

0

Обнаружена проблема - мне нужно было передать данные пользователя функции findOrCreate в правильном формате.

User.findOrCreate(profile._json, (err, user) => { 
     if (err) { 
     return done(err); 
     } 
     done(null, user); 
    })