如果在 passport.authenticate(...) 上删除 (req, res, next),网页会无限期地加载
Web page keeps loading indefinitely if removing (req, res, next) on 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
?声明字段的位置:对象 req
?
的 user
谢谢!
*编辑:这是一个调用另一个函数的函数...这是必需的,因为使用 next()
进行回调。 facebook 功能没有。
换句话说,当您调用 passport.authenticate
时,return 值实际上将是一个需要参数 req, res, next
的函数。通常你不需要包装它,因为它可以正常工作。但是,在这种情况下,有一个回调函数作为参数传入,并且该回调函数需要访问 next
参数。所以你必须包装整个东西才能访问那个 next
参数。
*注意:包装函数实际上并不是 return 任何东西 to/through 包装函数。 passport.authenticate()
return是一个函数,然后这个return函数用后面的参数组自调用。但是这第二个自调用函数结果没有被捕获为变量或 returned 或任何东西。
原因是重要的是要么使用res
参数发送响应要么允许express继续到下一层middleware/etc通过调用 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
包存储。
我从网上下载了一个示例项目。下面是一些代码片段:
在 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
?声明字段的位置:对象req
? 的
user
谢谢!
*编辑:这是一个调用另一个函数的函数...这是必需的,因为使用 next()
进行回调。 facebook 功能没有。
换句话说,当您调用 passport.authenticate
时,return 值实际上将是一个需要参数 req, res, next
的函数。通常你不需要包装它,因为它可以正常工作。但是,在这种情况下,有一个回调函数作为参数传入,并且该回调函数需要访问 next
参数。所以你必须包装整个东西才能访问那个 next
参数。
*注意:包装函数实际上并不是 return 任何东西 to/through 包装函数。 passport.authenticate()
return是一个函数,然后这个return函数用后面的参数组自调用。但是这第二个自调用函数结果没有被捕获为变量或 returned 或任何东西。
原因是重要的是要么使用res
参数发送响应要么允许express继续到下一层middleware/etc通过调用 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
包存储。