Веб-страница продолжает загружаться бесконечно, если удалить (req, res, next) на passport.authenticate(...)

Я скачал один пример проекта из интернета. Ниже приведены некоторые фрагменты кода:

На routes У меня есть файл (просто фрагмент):

var authController = require('./controllers/authController'),
var passport = require('passport');
var authLoginFacebook =
    passport.authenticate(
        'facebook',
        {
            session: false,
            scope: ['public_profile', 'email']
        }
    );
var checkJwt = function(req, res, next) {
    passport.authenticate(
        'jwt',
        {session: false },
        function (err, user, info) {
            next();
        }
    )(req, res, next);
}

module.exports = function(app) {
    // ...
    app.get(
        '/api/auth/login/facebook/callback',
        checkJwt,
        authLoginFacebook,
        authController.login
    );
    // ...
}

На passport У меня есть файл (просто фрагмент):

var User = require('../models/user');
var credentials = require('./credentials');
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;

module.exports = function(passport) {

    passport.use(
        new JwtStrategy({
                secretOrKey: credentials.secret,
                jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
            },
            function(payload, done) {
                User.findById(
                    payload._id,
                    function(err, user) {
                        if (err) {
                            return done(err, false);
                        }
                        if (user) {
                            return done(null, user);
                        } else {
                            return done(null, false);
                        }
                    }
                );
            }
        )
    );

    var fbStrategy = credentials.facebook;
    fbStrategy.passReqToCallback = true;
    passport.use(new FacebookStrategy(fbStrategy,
        function(req, token, refreshToken, profile, done) {
            // asynchronous
            process.nextTick(function() {
                // check if the user is already logged in
                if (!req.user) {
                    User.findOne({
                        'facebook.id': profile.id
                    }, function(err, user) {
                        if (err)
                            return done(err);
                        if (user) {
                            // if there is a user id already but no token (user was linked at one point and then removed)
                            if (!user.facebook.token) {
                                user.facebook.token = token;
                                user.facebook.name = profile.name.givenName + ' ' + profile.name.familyName;
                                user.facebook.email = (profile.emails[0].value || '').toLowerCase();
                                user.save(function(err) {
                                    if (err)
                                        return done(err);
                                    return done(null, user);
                                });
                            }
                            return done(null, user); // user found, return that user
                        } else {
                            // if there is no user, create them
                            var newUser = new User();
                            newUser.facebook.id = profile.id;
                            newUser.facebook.token = token;
                            newUser.facebook.name = profile.name.givenName + ' ' + profile.name.familyName;
                            newUser.facebook.email = (profile.emails[0].value || '').toLowerCase();
                            newUser.save(function(err) {
                                if (err)
                                    return done(err);
                                return done(null, newUser);
                            });
                        }
                    });
                } else {
                    // user already exists and is logged in, we have to link accounts
                    var user = req.user; // pull the user out of the session
                    user.facebook.id = profile.id;
                    user.facebook.token = token;
                    user.facebook.name = profile.name.givenName + ' ' + profile.name.familyName;
                    user.facebook.email = (profile.emails[0].value || '').toLowerCase();
                    user.save(function(err) {
                        if (err)
                            return done(err);
                        return done(null, user);
                    });
                }
            });
        })
    );

    // ...
};

У меня есть несколько вопросов здесь:

  1. почему на: passport.authenticate('jwt', ... переданы эти аргументы: (req, res, next) и на passport.authenticate('facebook', ... не в то время как они используются в одной строке один рядом с другим?

    app.get(
        '/api/auth/login/facebook/callback',
        checkJwt,
        authLoginFacebook,
        authController.login
    );
    

    Если я уберу эти аргументы, то веб-страница будет загружаться бесконечно.

  2. почему внутри: passport.use(new FacebookStrategy определено: req.user? где было объявлено поле: user для объекта req?

Спасибо!

1 ответ

Решение

* Редактировать: это функция, вызывающая другую функцию... которая требуется из-за обратного вызова, использующего next(), Функция Facebook не имеет этого.

Другими словами, когда вы вызываете passport.authenticateвозвращаемое значение на самом деле будет функцией, ожидающей параметры req, res, next, Обычно вам не нужно оборачивать это, потому что это просто работает. Однако в этом случае в качестве аргумента передается функция обратного вызова, и этой функции обратного вызова необходим доступ к next параметр. Таким образом, вы должны обернуть все это, чтобы получить доступ к этому next параметр.

* Примечание: упакованная функция на самом деле ничего не возвращает в / через функцию переноса. passport.authenticate() возвращает функцию, а затем эта возвращаемая функция вызывается самостоятельно с последующей группой параметров. Но этот второй самозванный результат функции не фиксируется как переменная, не возвращается или что-либо еще.

Причина в том, что важно либо отправить ответ, используя res параметр или позволяя Express перейти к следующему уровню промежуточного программного обеспечения / и т.д., вызвав next() параметр обратного вызова. Все это происходит асинхронно, и поток направляется с помощью обратных вызовов.

var checkJwt = function(req, res, next) {
    passport.authenticate(
        'jwt',
        {session: false },
        function (err, user, info) {
            next();
        }
    )(req, res, next);
}

req.user будет пользователем предыдущей учетной записи, которую я считаю, что passport.js обычно хранит, используя express-session пакет.

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