在passport[configure authentication]文档中,它有一个看起来相当可怕的函数,它使用了神秘的函数"done"
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
现在,在express文档中,有相当多的方法可以传递名为next的东西。
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500).send('Something broke!');
});
这就是express和passport这两个框架之间的区别吗?还是他们在做两件不同的事情?
这就是express和passport这两个框架之间的区别吗
不,它们的用途不同。Express被用作node.js上的应用程序框架,其中as passport只处理web应用程序的身份验证部分。
关于next()
next()是connect的一部分,inturn是一个表达式依赖项。调用next()的目的是触发express堆栈中的下一个中间件。
为了更容易地理解next()
概念,您可以在此处查看一个基于express构建的示例应用程序。
正如您在所指向的行中看到的,应用程序使用路由级中间件来检查用户是否登录。
app.get('/account', ensureAuthenticated, function(req, res){
这里ensureAuthenticated是像一样在底部定义的中间件
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
正如您所看到的,如果用户通过了身份验证,函数会调用next()
并将控制权传递给上面写的路由处理程序中的下一层,否则即使不调用next()
,它也会重定向到另一个路由
关于done()
done()用于触发我们为护照身份验证编写的返回url处理程序。要了解更多关于如何完成的工作,您可以查看passport此处的代码示例,并查看标题为自定义回调的部分
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);
});
这里,passport.authenticate
的第二个参数是您将从passport策略调用的done()
的定义。
注释
在这里,通过我上面提供的两个链接中的示例代码,在理解其行为方面比文档有很大帮助。我建议你也这样做。
passport的done()希望您为第一个参数传递一个错误(或null),并将一个用户对象作为第二个参数。
express的next()希望在第一个参数中出现错误,或者在没有错误的情况下完全不使用参数进行调用。您也可以在第一个参数中传递将控制重定向到的路由的名称,但这不是很常见的
让我们备份,因为我认为您可能有一些困惑。
Express是一个web应用程序框架。从广义上讲,它负责引导用户访问资源。
Passport是一个身份验证框架。它负责确保允许用户访问所述资源。
在这两个框架中都有中间件的概念。中间件基本上是广义的控制流。例如,在某些Express框架中,您可以说:
-
请求路由
/user/:x
时,确保参数x有效- 如果有效,则next()-->,这意味着转到下一个中间件函数()
-
确保用户有会话等
-
当所有中间件都执行完毕后,我们执行应用程序
例如,
router.get('/', function(req, res) { // when the '/' route is requested
res.render('index', { title: 'Express' }); // send index.html
});
在Passport中,他们也使用中间件的思想,但是,他们使用done()而不是next()而且有点复杂。有关详细信息,请参阅此页面
http://toon.io/understanding-passportjs-authentication-flow/
next()
将获得到下一个中间件的控制流(如果有)。
在Passport.js中,调用done()
将使流跳回到passport.authenticate()
。它传递了错误、用户和附加信息对象(如果已定义)。
在其他情况下,done()
将把控制流带到它在其中使用的函数之后的下一个函数。