nodejs护照'done()'的困惑

时间:2018-09-02 20:26:02

标签: javascript node.js authentication google-api

我一直关注theNetNinjas的youtube系列,以创建带有护照的身份验证页面。但是这个视频让我很困惑。

const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20');
const keys = require('./keys');
const User = require('../../../models/authDatabase');

passport.serializeUser((user, done) => {       //  THIS TRIGGERS SECOND <----
    done(null, user.id);
});

passport.deserializeUser((id, done) => {     // THIS TRIGGERS THIRD <----
    User.findById(id).then(user => {
        done(null, user.id);
    });
});

passport.use(            // THIS TRIGGERS FIRST <-------
        new GoogleStrategy({
            // options for the google strat
            clientID: keys.google.clientID,
            clientSecret: keys.google.clientSecret,
            callbackURL: '/projects/auth/google/redirect'
        }, (accessToken, refreshToken, profile, done) => {
            // passport callback function
            console.log('passport callback function fired');
            User.findOne({googleId: profile.id}).then(user => {
                if (user) {
                    // The user is already registered
                    console.log('user is:', user.googleId);
                    done(null, currentUser);
                } else {
                    // if not, create user in our db
                    new User({
                        username: profile.displayName,
                        googleId: profile.id
                    }).save().then(newUser => {
                        console.log('new user created:' + newUser);
                        done(null, newUser)
                    })
                }
            });
        })
);

我很奇怪done方法如何知道下一步该怎么做。起初,我认为它是基于顺序的,因此它触发了在调用该函数下定义的下一个函数,但是显然情况并非如此,因为您可以看到它跳到顶部并运行passport.serializeUser ,为什么呢?

以另一种方式询问:done方法如何知道如何触发passport.serializeUser函数而不是passport.deserializeUser函数?

1 个答案:

答案 0 :(得分:0)

因为不仅只有一个done函数。每当您将其用作参数时,Passport都会将其作为参数传递,并且取决于用法,它们可能会以不同的方式传递。简化示例:

 function GoogleStrategy(options, callback) {
   callback(1, 2, 3, function strategyDone(error, user) {
    serializeUser(user, function serializeDone(error, id) {
      //...
    });
  });
 }