node.js回调中'done'和'next'之间的差异

时间:2014-10-02 16:03:02

标签: javascript node.js express passport.js

在护照[configure authentication]文档中,它有一个相当可怕的功能,使用了神秘的功能"已完成。'

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 documentation中有很多方法可以传递下一个叫做的东西。

app.use(function(err, req, res, next){
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

这是两个框架,快递和护照之间的区别吗?或者他们分别做两件事?

4 个答案:

答案 0 :(得分:18)

这是两个框架,快递和护照之间的区别吗?

它们的用途与它们的目的不同。 Express用作node.js上的应用程序框架,其中passport只处理Web应用程序的身份验证部分。

关于next()

next()是connect的一部分,其中inturn是一个表达式依赖项。调用next()的目的是触发express堆栈中的下一个中间件。

要以更简单的方式理解next()概念,您可以查看基于express here构建的示例应用。

正如您所指出的那样,应用程序使用路由级中间件来检查用户是否已登录。

app.get('/account', ensureAuthenticated, function(req, res){

这里确认是经过验证的中间件,它在底部定义,如

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) { return next(); }
  res.redirect('/login')
}

正如您可以看到用户是否经过身份验证,该函数调用next()并将控制权传递给上面编写的路由处理程序中的下一层,否则即使不调用next()

关于done()

另一方面,

done()用于触发我们为护照身份验证编写的返回URL处理程序。要了解有关完成方式的更多信息,您可以查看passport here处的代码示例,并查看标题为自定义回调

的部分
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的第二个参数是您将从护照策略中调用的done()的定义。

注释

在这里,我在上面提供的两个链接中的示例代码有助于理解其行为而不是文档。我建议你也这样做。

答案 1 :(得分:5)

passport's done()希望您为第一个参数传递错误(或为null),并将用户对象作为第二个参数传递。

如果没有错误,

express的next()想要第一个参数中的错误或者根本没有参数被调用。你也可以在第一个参数中传递路由的名称以重定向控制,但这不常见

答案 2 :(得分:4)

让我们回来,因为我觉得你可能会有些困惑。

Express是一个Web应用程序框架。从广义上讲,它负责将用户引导到资源。

Passport是一种身份验证框架。它负责确保允许用户访问所述资源。

在这两个框架中都有一个中间件的概念。中间件基本上是通用控制流程。 例如,在某些Express框架中,您可以说:

  1. 请求路线/user/:x

    时确保参数x有效
    • 如果有效,则next() - >这意味着转到下一个中​​间件函数()
  2. 确保用户有会话等

  3. 当所有中间件都已执行时,我们执行应用程序

  4. 例如,

    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/

答案 3 :(得分:0)

next()将控制流转移到下一个中​​间件(如果有)。

在Passport.js中, 调用done()将使流程跳回到passport.authenticate()。它传递了错误,用户和其他信息对象(如果已定义)。

在其他情况下,done()将把控制流带到使用该函数之后的下一个函数。