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

Tar*_*oys 17 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);
    });
   }
));
Run Code Online (Sandbox Code Playgroud)

现在,在快速文档中,有很多方法可以传递下一个名为next的东西.

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

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

mit*_*esh 18

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

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

关于next()

next()是connect的一部分,inturn是一个明确的依赖.调用next()的目的是触发express堆栈中的下一个中间件.

next()以更简单的方式理解这个概念,您可以查看在此处构建的示例应用程序.

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

app.get('/account', ensureAuthenticated, function(req, res){
Run Code Online (Sandbox Code Playgroud)

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

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) { return next(); }
  res.redirect('/login')
}
Run Code Online (Sandbox Code Playgroud)

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

关于完成()

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

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);
});
Run Code Online (Sandbox Code Playgroud)

这里第二个参数passport.authenticatedone()您要从护照策略中调用的定义.

注意

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


Rob*_*evy 5

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

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


小智 5

让我们备份一下,因为我认为您可能有些困惑。

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

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

在这两个框架中都有中间件的想法。中间件基本上是广义的控制流。例如,在某些 Express 框架中你可以说:

  1. 请求路由时确保参数x有效/user/:x

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

  3. 当所有中间件都执行完毕后,我们就执行应用程序

例如,

router.get('/', function(req, res) { // when the '/' route is requested
    res.render('index', { title: 'Express' }); // send index.html
});
Run Code Online (Sandbox Code Playgroud)

在 Passport 中,他们也使用了中间件的思想,但是,他们使用的不是 next(),而是 did(),而且它有点复杂。请参阅此页面了解更多信息
http://toon.io/understanding-passportjs-authentication-flow/