web-dev-qa-db-ja.com

node.jsコールバックの「done」と「next」の違い

パスポート[認証の構成]のドキュメントには、不思議な機能「完了」を使用したかなり怖い機能があります。

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);
    });
   }
));

さて、 エクスプレスドキュメント には、nextと呼ばれるものを渡すメソッドがかなりあります。

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

これは、エクスプレスとパスポートの2つのフレームワークの違いですか?それとも彼らは2つの別々のことをしていますか?

17
Tara Roys

これは、2つのフレームワーク、エクスプレスとパスポートの違いですか?

いいえ、使用目的が異なります。 Expressはnode.jsのアプリケーションフレームワークとして使用されますが、passportはWebアプリケーションの認証部分を処理するだけです。

next()について

next()はconnectの一部であり、これは明示的な依存関係です。 next()を呼び出す目的は、Expressスタックの次のミドルウェアをトリガーすることです。

next()の概念をより簡単に理解するために、 express here 上に構築されたサンプルアプリを見ることができます。

指摘された行でわかるように、アプリケーションはルートレベルのミドルウェアを使用して、ユーザーがログインしているかどうかを確認します。

_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ハンドラーをトリガーするために使用されます。完了した動作の詳細を理解するには、 ここのパスポート のコードサンプルを見て、カスタムコールバックというタイトルのセクションを確認してください。

_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_の2番目のパラメーターは、パスポート戦略から呼び出すdone()の定義です。

注意

ここで、上記の2つのリンクのサンプルコードを確認することで、ドキュメントよりもその動作を理解するのに大いに役立ちました。同じことをすることをお勧めします。

18
mithunsatheesh

passportのdone()は、最初のパラメーターにエラー(またはnull)を渡し、2番目のパラメーターとしてユーザーオブジェクトを渡すように求めています。

expressのnext()は、最初のパラメーターにエラーがあるか、エラーがなかった場合はパラメーターなしで呼び出されることを望んでいます。最初のパラメータでコントロールをリダイレクトするルートの名前を渡すこともできますが、これはあまり一般的ではありません

5
Robert Levy

混乱するかもしれないので、バックアップしましょう。

ExpressはWebアプリケーションフレームワークです。非常に広い意味で、ユーザーをリソースに誘導する責任があります。

パスポートは認証フレームワークです。ユーザーが上記のリソースにアクセスできるようにする責任があります。

どちらのフレームワークにも、ミドルウェアのアイデアがあります。ミドルウェアは基本的に一般化された制御フローです。たとえば、一部の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
});

Passportでは、ミドルウェアの概念も使用していますが、next()の代わりにdone()を使用しているため、少し複雑です。詳細については、このページを参照してください
http://toon.io/understanding-passportjs-authentication-flow/

4
Jason