Mô-đun xác thực 'Hộ chiếu' yêu cầu phương thức FindOrCreate để đăng nhập. Tôi đang sử dụng mongoose để tiết kiệm người dùng của tôi với sơ đồ sau:Cách xử lý async. Phương thức findOrCreate cho hộ chiếu và mongoose
var UserSchema = new Schema({
firstname: String,
lastname: String,
email: String,
accounts: []
});
Mảng tài khoản giữ đối tượng đại diện cho tài khoản facebook, như {provider: "facebook", uid: "someFacebookId"}
.
chiến lược xác thực của tôi trông như thế này:
// 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);
});
}
});
});
}
));
Vấn đề: Sau khi truy vấn cơ sở dữ liệu của tôi (User.find(...)
) chức năng gọi lại được thực hiện ngay lập tức mà không cần chờ cho cơ sở dữ liệu của tôi để trả lời. Điều này dẫn đến một đối tượng không xác định olduser
. Vì vậy, tôi nhận được một cộng hòa của cùng một người dùng vào cơ sở dữ liệu của tôi mỗi khi người dùng này cố gắng đăng nhập.
Làm cách nào để xử lý cuộc gọi lại không đồng bộ này một cách chính xác?
Tôi biết điều này không liên quan trực tiếp đến câu hỏi, nhưng không phải là tìm truy vấn có chút nguy hiểm không? Nó tìm kiếm một người dùng với bất kỳ accounts.uid nào của giá trị đã cho và với bất kỳ accounts.provider nào của 'facebook'. Nhưng điều gì buộc họ phải là cùng một yếu tố danh sách tài khoản? Đó là, nếu một người dùng khác có một uid phù hợp với một nhà cung cấp khác thì sao? – StevenC
Tôi giả sử nó đang tìm kiếm sự kết hợp của cả hai giá trị, mà nên là duy nhất. – Sven
Giả định này là nguy hiểm. Bởi vì tìm trong mảng tài khoản phù hợp nếu người dùng có tài khoản facebook và tài khoản * BẤT K * * có uid. Nếu ai đó có một máy chủ OpenAuth, sau đó ông có thể đăng nhập như bất kỳ người dùng bằng cách trả lại uid ông muốn. – tangxinfa