Веб-страница продолжает загружаться бесконечно, если удалить (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);
});
}
});
})
);
// ...
};
У меня есть несколько вопросов здесь:
почему на:
passport.authenticate('jwt', ...
переданы эти аргументы:(req, res, next)
и наpassport.authenticate('facebook', ...
не в то время как они используются в одной строке один рядом с другим?app.get( '/api/auth/login/facebook/callback', checkJwt, authLoginFacebook, authController.login );
Если я уберу эти аргументы, то веб-страница будет загружаться бесконечно.
почему внутри:
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
пакет.