web-dev-qa-db-ja.com

nodejs / passportを使用して不正なリクエストを処理する方法

ドキュメント のように、このように認証要求を処理した場合、成功した試行をキャプチャできます。

app.post('/login',
  passport.authenticate('local'),
  function(req, res) {
    // If this function gets called, authentication was successful.
    // `req.user` contains the authenticated user.
    res.redirect('/users/' + req.user.username);
  });

しかし、ドキュメントが言うように:

デフォルトでは、認証が失敗した場合、Passportは401 Unauthorizedステータスで応答し、追加のルートハンドラーは呼び出されません。認証が成功した場合、次のハンドラーが呼び出され、req.userプロパティが認証されたユーザーに設定されます。

不正なログイン試行を処理するにはどうすればよいですか?

カスタムミドルウェアで処理できることは知っていますが、もっと良い方法はありますか?

12
Adam K Dean

passport docsCustom Callbackセクションを見て、オーバーライドする方法について説明しているはずです。認証要求を処理する組み込みの動作。ストラテジーから呼び出すdone関数の目的を果たすカスタムコールバックを作成できます。

app.get('/login', function(req, res, next) {
  /* look at the 2nd parameter to the below call */
  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関数を参照してください。これは、パスポート用に定義するローカル戦略です。 API呼び出しまたはdb操作からの応答に従って、ストラテジーから設定されたerruserinfoなどのさまざまな使用可能なパラメーターを使用して、done関数を呼び出すことができます。これらのパラメーターは、passport.authenticate呼び出しで上記の関数定義によって処理されます。

passport.use(new LocalStrategy(
  function(username, password, done) {
    /* see done being invoked with different paramters
       according to different situations */
    User.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) { return done(null, false); }
      if (!user.verifyPassword(password)) { return done(null, false); }
      return done(null, user);
    });
  }
));
15
mithunsatheesh

私の場合、401エラー(「デフォルトの動作」)は必要ありませんでした。ユーザーが許可されていない場合は、単純なリダイレクトが必要でした。 PassportJSドキュメント (「概要」および「リダイレクト」ヘッダー内)で説明されているように、単純な_{ failureRedirect: '/login' }_が機能しました。

認証には複雑さが伴いますが、コードを複雑にする必要はありません。

_app.post('/login', passport.authenticate('local', { successRedirect:'/',
                                                    failureRedirect: '/login' }));
_

この場合、リダイレクトオプションはデフォルトの動作を上書きします。認証が成功すると、ユーザーはホームページにリダイレクトされます。認証が失敗した場合、ユーザーは別の試行のためにログインページにリダイレクトされます。

受け入れられた答えはあなたにもっと柔軟性を与えます。しかし、この答えは少し簡単です。

「失敗」には、ユーザーがいない場合も含まれると確信しています:if (!user)、しかし私はnot確信しています失敗にエラーケースが含まれるかどうか:if (err)受け入れられた回答。

2
The Red Pea