Das Authentifizierungsmodul 'Passport' erfordert eine FindOrCreate-Methode, um eine Anmeldung durchzuführen. Ich bin mit Mungo, um meine Benutzer mit dem folgenden Schema zu speichern:Wie mit Async umzugehen. findOrCreate-Methode für Pass und Mungo
var UserSchema = new Schema({
firstname: String,
lastname: String,
email: String,
accounts: []
});
Die Konten Array-Objekte enthält, die Facebook-Konten darstellen, wie {provider: "facebook", uid: "someFacebookId"}
.
Meine Authentifizierungsstrategie sieht wie folgt aus:
// 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);
});
}
});
});
}
));
Problem: Nach meiner Datenbank abfragt (User.find(...)
) die Callback-Funktion sofort ausgeführt wird, ohne zu warten, für meine Datenbank zu beantworten. Dies führt zu einem undefinierten Objekt olduser
. Daher erhalte ich jedes Mal, wenn dieser Benutzer versucht, sich anzumelden, eine Kopie desselben Benutzers in meine Datenbank.
Wie gehe ich richtig mit diesem asynchronen Rückruf um?
ich weiß, dass dies nicht direkt auf die Frage bezieht, aber das ist nicht ein wenig gefährlich Abfrage finden? Es sucht nach einem Benutzer mit einer beliebigen accounts.uid des angegebenen Wertes und mit jedem accounts.provider von 'facebook'. Aber was zwingt sie dazu, dasselbe Element der Kontenliste zu sein? Was ist, wenn ein anderer Benutzer eine passende UID mit einem anderen Provider hat? – StevenC
Ich gehe davon aus, dass es die Kombination beider Werte sucht, die einzigartig sein sollte. – Sven
Diese Annahme ist Gefahr. Weil in einem Array von Accounts gefunden wird, die übereinstimmen, wenn der Benutzer einen Facebook-Account hat und der Account * ANY * diesen Account hat. Wenn jemand einen OpenAuth-Server hat, kann er sich als beliebiger Benutzer anmelden, indem er die gewünschte Benutzer-ID zurückgibt. – tangxinfa