Экспресс 4 + Паспорт, req.user не определен - порядок вызова функции?

Я столкнулся с очень специфической проблемой. Я пытался получить экспресс + паспорт на работу. Поскольку подавляющее большинство примеров в Интернете были для экспресс-3, процесс занял у меня какое-то время - в конце концов я заставил Google аутентификацию работать. Я пытался привязать учетную запись Google к локальной учетной записи, что требует поиска учетной записи из БД Mongo. Ниже приведена часть кода, которая работает:

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

//Deserialize function
passport.deserializeUser(function(obj, done) {
    done(null, obj);
});

//Strategy
passport.use(new GoogleStrategy({
        returnURL: 'http://localhost:8000/auth/google/return',
        realm: 'http://localhost:8000/'
    },
    function(identifier, profile, done) {

        process.nextTick(function() {

            profile.identifier = identifier;

            return done(null, profile);
        });

    }
));

Следующие коды были проверены для работы. Все работает как шарм. Однако, когда я изменил код следующим образом:

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

passport.deserializeUser(function(id, done) {

     //note that only change is to find user from database, User is a mongoose instance
     //very straightforward, verified user can be found.
     User.findById(id, function(err, user) {
        done(err, user);
     });
});

И стратегия была изменена, чтобы создать пользователя, если не найден:

        process.nextTick(function() {

             profile.id = identifier;

             User.findOne({
                 'google.id': profile.id
             }, function(err, user) {
                 if (err) {
                     return done(err); // don't even know what done means!
                 } else if (user) {
                     return done(null, user);
                 } else {
                     //very easy to create and save to database.
                     //create a new user instance
                     var newUser = new User();

                     newUser.google.id = profile.id;
                     newUser.google.name = profile.displayName;
                     newUser.google.email = profile.emails[0].value;

                     newUser.local.email = newUser.google.email;
                     newUser.local.name = newUser.google.name;
                     // newUser.id = newUser._id;

                     //it should have been saved to database?
                     newUser.save(function(err) {
                         if (err)
                             throw err;

                         //The done is called once is saved.
                         return done(null, newUser);
                     });
                 }
             });
         });

И это тот роутер, который был размещен после всей необходимой инициализации для паспорта.

app.get('/', function(req, res) {
    console.log("Rendering...");
    console.log(req.user);

    res.render('index', {
        user: req.user
    });

    console.log("Rendering done...");
});

Теперь вот забавная часть: когда я получаю доступ к URL, console.log в пределах app.get('/') был назван ПОСЛЕ загрузки страницы, и req.user НЕ является неопределенным. Когда он работал, console.log вызывался в правильном порядке. Кажется, что когда страница была отображена, req.user еще не был инициализирован - но я просто не могу понять, почему функции console.log назывались AFTER res.render - для меня это не имеет никакого смысла. Это может быть результатом некоторой асинхронной логики...

У кого-нибудь есть идеи? Спасибо. Я обновлю код Github,

Я тоже пробовал websocket чтобы получить доступ req.handshake.user - все данные есть. Это как-то просто когда res.render был вызван, он еще не был инициализирован.

0 ответов

Другие вопросы по тегам