update sequelize sails example create collection node.js authentication express mongoose passport.js

node.js - sails - sequelize v3



Cómo lidiar con la asincronización Método FindOrCreate para pasaporte y mangosta (4)

El módulo de autenticación ''Pasaporte'' requiere un método FindOrCreate para iniciar sesión. Estoy usando mangosta para salvar a mis usuarios con el siguiente esquema:

var UserSchema = new Schema({ firstname: String, lastname: String, email: String, accounts: [] });

El conjunto de cuentas contiene objetos que representan cuentas de Facebook, como {provider: "facebook", uid: "someFacebookId"} .

Mi estrategia de autenticación se ve así:

// Authentication Strategy passport.use(new FacebookStrategy({ clientID: CONFIG.fb.appId, clientSecret: CONFIG.fb.appSecret, callbackURL: CONFIG.fb.callbackURL }, function(accessToken, refreshToken, profile, done) { // asynchronous verification, for effect... process.nextTick(function () { User.find({ ''accounts.uid'': profile.id, ''accounts.provider'': ''facebook'' }, function(err, olduser) { if(olduser._id) { console.log(''User: '' + olduser.firstname + '' '' + olduser.lastname + '' found and logged in!''); done(null, olduser); } else { var newuser = new User(); var account = {provider: "facebook", uid: profile.id}; newuser.accounts.push(account); newuser.firstname = profile.name.givenName; newuser.lastname = profile.name.familyName; newuser.email = "TBD..."; newuser.save(function(err) { if(err) { throw err; } console.log(''New user: '' + newuser.firstname + '' '' + newuser.lastname + '' created and logged in!''); done(null, newuser); }); } }); }); } ));

Problema: Después de consultar mi base de datos ( User.find(...) ) la función de devolución de llamada se ejecuta inmediatamente sin esperar a que mi base de datos responda. Esto da como resultado un objeto olduser indefinido. Así que estoy recibiendo una copia del mismo usuario en mi base de datos cada vez que este usuario intenta iniciar sesión.

¿Cómo manejo esta devolución de llamada asincrónica correctamente?


User.find devuelve una matriz de documentos que coinciden con sus condiciones. En su caso, desea usar User.findOne en User.findOne lugar, y luego verificar if (olduser)... para determinar si se encontró un documento coincidente.


process.nextTick(function () { var query = User.findOne({ ''fbId'': profile.id }); query.exec(function (err, oldUser) { console.log(oldUser); if(oldUser) { console.log(''User: '' + oldUser.name + '' found and logged in!''); done(null, oldUser); } else { var newUser = new User(); newUser.fbId = profile.id; newUser.name = profile.displayName; newUser.email = profile.emails[0].value; newUser.save(function(err) { if(err) {throw err;} console.log(''New user: '' + newUser.name + '' created and logged in!''); done(null, newUser); }); } }); });