0

我从互联网上下载了一个示例项目。下面是一些代码片段:

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. 为什么 on: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

谢谢!

4

1 回答 1

0

*编辑:这是一个调用另一个函数的函数......这是必需的,因为回调使用next(). facebook 功能没有。

换句话说,当你调用时passport.authenticate,返回值实际上是一个期望参数的函数req, res, next。通常你不需要包装它,因为它可以工作。但是,在这种情况下,有一个回调函数作为参数传入,并且该回调函数需要访问该next参数。因此,您必须包装整个事物才能访问该next参数。

*注意:被包装的函数实际上并没有通过包装函数返回任何东西。passport.authenticate()返回一个函数,然后用后面的参数组自调用这个返回函数。但是这第二个自调用函数结果不会被捕获为变量或返回或任何东西。

原因是重要的是要么使用res参数发送响应,要么next()通过调用回调参数允许 express 继续到中间件/等的下一层。这一切都是异步发生的,并且使用回调来引导流程。

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包存储。

于 2018-06-13T23:22:56.770 回答