我从互联网上下载了一个示例项目。下面是代码的一些片段:
在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', ...
,而不是在同一行中使用它们?< / p>
app.get(
'/api/auth/login/facebook/callback',
checkJwt,
authLoginFacebook,
authController.login
);
如果删除这些参数,则网页会无限期地加载。
为什么内部:passport.use(new FacebookStrategy
已定义:req.user
?在哪里声明了对象user
对象req
?
谢谢!
答案 0 :(得分:0)
*编辑:这是一个调用另一个函数的函数...由于使用next()
进行回调,这是必需的。 facebook功能没有。
换句话说,当您调用passport.authenticate
时,返回值实际上将是一个期望参数req, res, next
的函数。通常你不需要包装它,因为它只是起作用。但是,在这种情况下,有一个回调函数作为参数传入,并且该回调函数需要访问next
参数。因此,您必须包装整个事件才能访问该next
参数。
*注意:包装函数实际上并没有通过包装函数返回任何内容。 passport.authenticate()
返回一个函数,然后使用后面的参数组自行调用此返回函数。但是这第二个自我调用的函数结果不会被捕获为变量或返回或任何东西。
原因是重要的是使用res
参数发送响应或允许express通过调用{{1}继续到下一层中间件/ etc回调参数。它全部异步发生,并使用回调来指示流。
next()
req.user将是以前登录的用户,我相信passport.js通常使用var checkJwt = function(req, res, next) {
passport.authenticate(
'jwt',
{session: false },
function (err, user, info) {
next();
}
)(req, res, next);
}
包存储。