71

Node.js + Express.js アプリケーションのエラー処理の原則に関するこの質問を介して、ノードでエラー処理がどのように機能するかを見てきました。、しかし、認証に失敗したときにパスポートが何をしているのかわかりません。次の LocalStrategy があります。

passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' },
  function(email, password, next) {
 
    User.find({email: UemOrUnm}, function(err, user){
      if (err) { console.log('Error > some err'); return next(err); }
      if (!user) { console.log('Error > no user'); return next('Incorrect login or password'); } 

      if (password != user.password) {
        return next(Incorrect login or password);
      }
      return next(null, user);
    });
  }
));

「Error > some err」というコンソールの出力が表示された後、他に何も起こりません。エラーパラメーターを使用して次のパスを続行する必要があると思いますが、そうではないようです。どうしたの?

4

4 に答える 4

171

戦略の実装はpassport.authenticate、リクエストの認証と成功/失敗の処理の両方に関連して機能します。

このルートを使用しているとします (電子メール アドレスとパスワードが渡されます)。

app.post('/login', passport.authenticate('local', {
  successRedirect: '/loggedin',
  failureRedirect: '/login', // see text
  failureFlash: true // optional, see text as well
});

これにより、戦略のコードが呼び出され、次の 3 つの条件のいずれかが発生する可能性があります。

  1. ユーザーの情報をフェッチしようとして内部エラーが発生しました (データベース接続が切断されたとします)。このエラーは次のように渡されます: next(err); これは Express によって処理され、HTTP 500 応答が生成されます。
  2. 指定された資格情報が無効です (指定された電子メール アドレスを持つユーザーがいないか、パスワードが一致しません)。その場合、エラーは生成されませんがfalse、ユーザー オブジェクトとしてa を渡しますnext(null, false)。これによりトリガーされfailureRedirectます (定義しない場合、HTTP 401 Unauthorized 応答が生成されます);
  3. すべてがチェックアウトされ、有効なユーザー オブジェクトが得られたので、それを渡しますnext(null, user)successRedirectこれにより、 ;がトリガーされます。

無効な認証 (内部エラーではない) の場合、コールバックとともに追加のメッセージを渡すことができます。

next(null, false, { message : 'invalid e-mail address or password' });

connect-flash ミドルウェアを使用failureFlash してインストールした場合、提供されたメッセージはセッションに保存され、たとえばテンプレートで使用するために簡単にアクセスできます。

編集:認証プロセスの結果を自分で完全に処理することもできます (Passport がリダイレクトまたは 401 を送信する代わりに):

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (! user) {
      return res.send({ success : false, message : 'authentication failed' });
    }
    // ***********************************************************************
    // "Note that when using a custom callback, it becomes the application's
    // responsibility to establish a session (by calling req.login()) and send
    // a response."
    // Source: http://passportjs.org/docs
    // ***********************************************************************
    req.login(user, loginErr => {
      if (loginErr) {
        return next(loginErr);
      }
      return res.send({ success : true, message : 'authentication succeeded' });
    });      
  })(req, res, next);
});
于 2013-03-29T21:13:36.513 に答える
22

クリスチャンが言っていたのは、関数を追加する必要があるということでした

req.login(user, function(err){
  if(err){
    return next(err);
  }
  return res.send({success:true});
});

したがって、ルート全体は次のようになります。

app.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (! user) {
      return res.send(401,{ success : false, message : 'authentication failed' });
    }
    req.login(user, function(err){
      if(err){
        return next(err);
      }
      return res.send({ success : true, message : 'authentication succeeded' });        
    });
  })(req, res, next);
});

ソース: http://passportjs.org/guide/login/

于 2015-05-12T20:00:37.040 に答える
3

req.logIn(function (err) { });コールバック関数内に成功リダイレクトを追加して実行する必要があります

于 2015-02-20T17:44:58.100 に答える
0

しばらく経ち、最も適切なコードは次のようになります。

  passport.authenticate('local', (err, user, info) => {
    if (err) {
      return next(err); // will generate a 500 error
    }
    // Generate a JSON response reflecting authentication status
    if (!user) {
      return res.status(401).send({ error: 'Authentication failed' });
    }
    req.login(user, (err) => {
      if (err) {
        return next(err);
      }
      return res.status(202).send({ error: 'Authentication succeeded' });    
    });
});
于 2021-10-06T04:47:01.583 に答える