我正在查看passport.js文档,我注意到了这段代码:
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/login'); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
那里的倒数第二行(req,res,next)发生了什么?
根据我的理解,这不是IIFE的正确语法或上下文,req,res和next应该已经可用于authenticate函数。
谢谢,
Zakiir
答案 0 :(得分:1)
passport.authenticate()
返回一个中间件函数。
即。它有签名fn(req, res, next)
。
当你想在一个路径中运行它时,你必须自己调用它并传递那些参数,以便它可以,例如,从请求访问数据,操纵响应等。
app.get('/login', function(req, res, next) {
passport.authenticate('local')(req, res, next);
});
运行您的本地策略并执行它配置的任何操作。
你刚刚写了这个:
app.get('/login', function(req, res, next) {
passport.authenticate('local')();
});
req
功能无法使用res
,next
和authenticate
。
简单地调用函数不会让它访问调用站点范围内的变量。例如,这不起作用:
function addOne() {
x++;
}
app.get('/', function() {
var x = 99;
addOne();
})
当你定义一个函数时,函数可以随时随地在定义站点访问范围内的变量。
您的代码段传入(定义)在本地策略运行后运行的回调,该回调允许您在本地策略成功或无法对用户进行身份验证后运行任意逻辑。
app.get('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) return next(err);
if (!user) return res.redirect('/login');
req.logIn(user, function(err) {
if (err) return next(err);
return res.redirect('/users/' + user.username);
});
})(req, res, next);
});
此回调可以访问req
,res
和next
,因为在定义回调函数时它们在范围内。
但是,在调用护照的req
功能时,您仍需要通过res
,next
和authenticate
,以便它可以访问它们。该函数已在库中定义,因此,与定义的回调函数不同,它不会捕获路径中的res
,res
和next
变量。
当运行定义的回调函数时,范围内的req / res变量可能已被authenticate
运行的本地策略中发生的任何变化所突变。回调函数可以读取变量的状态并完全具有最终结果 - 它本质上是对authenticate
方法的结果进行后处理,允许您完全自由地编写自己的逻辑,如果Passport&# 39;内置选项还不够。
调用站点与函数定义站点之间的作用域行为的差异导致了令人困惑的片段。