3

Я считаю, что имею дело с состоянием гонки на Node.js с использованием PassportJS (в частности, passport-local).Node.js Вход в систему Вход в систему Race Condition

Вот мой Router для регистрации:

router.post('/', upload.single('avatar'), function(req, res, next) { 
    var userType = req.body.userType; 
    var username = req.body.username; 
    var password = req.body.password; 
    var email = req.body.email; 
    // Convert Buffer data to base64 encoded string 
    var base64Avatar = new Buffer(req.file.buffer).toString('base64'); 
    var avatar = 'data:' + req.file.mimetype + ';base64,' + base64Avatar; 

    var createdUser; 
    if (userType == 'viewer') { 
     createdUser = new user.User(username, password, email, [], [], avatar).getInstance(); 
    } else if (userType == 'contributor') { 
     createdUser = new contributor.Contributor(username, password, email, [], [], avatar, []).getInstance(); 
    } 

    req.login(createdUser, function(err) { 
     if (err) { return next(err); } 
     req.session.save(function() { 
      res.redirect('/user/' + req.user.username); 
     }); 
    }); 
}); 

В constructor в User модели с использованием TypeScript:

constructor(private _username: String, private _password: String, private\ 
_email: String, private _favorites: Array<any>, private _inbox: Array<any>, \ 
private _avatar: String) { 
     this._modelInstance = new userModel({username: _username, password: _\ 
password, email: _email, favorites: _favorites, inbox: _inbox, avatar: _avata\ 
r}); 
     this._modelInstance.save(); 
}; 

Я пытался применять async.series к:

а) Создание экземпляра модели и сохранение в классе пользователя constr uctor.

b) createdUser создание по маршруту и ​​запрос req.login.

Я также попытался (как вы можете видеть) сохранить файл session вручную и использовать перенаправление в качестве обратного вызова, чтобы гарантировать сохранение сеанса. Я также посмотрел на Buffer, и это кажется синхронным, поэтому я не считаю, что это проблема.

Если я позвоню модели User с короткой строкой, такой как myAvatar, тогда она будет правильно войти в систему. Только когда строка аватара становится большой. В этом случае пользователь может войти в систему после, но автоматический вход в систему не выполняется через req.login.

Он также сообщает, что профиль пользователя, который перенаправляется на него, не отображается сразу после входа в систему, сигнализируя, что он пытается войти в систему до того, как модель будет сохранена (страница профиля выполняет запрос базы данных, и это не является пока не нашел ничего). Однако обновление после перенаправления показывает данные на странице профиля.

Я вижу где-то асинхронную проблему?

ответ

0

Перемещение save() логики к регистрации Router исправлено.

Тогда я мог бы просто добавить req.login вызов к save() обратного вызова:

createdUser.save(function(err, data) { 
    if (err) { 
      console.log(err); 
    } else { 
     req.login(createdUser, function(err) { 
      if (err) { return next(err); } 
      req.session.save(function() { 
       res.redirect('/user/' + req.user.username); 
      }); 
     }); 
    } 
});