web-dev-qa-db-ja.com

Express Passport(node.js)エラー処理

this stack exchange を使用してノードでエラー処理がどのように機能するかを見てきましたが、認証に失敗したときにどのパスポートが実行するのかわかりません。次の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」コンソールの出力が表示された後、他に何も起こりません。エラーパラメーターを使用して次のパスに進む必要があると思いますが、そうは思えません。どうしたの?

64
Omid Ahourai

戦略の実装は_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を渡します:next(null, false);これによりfailureRedirectがトリガーされます(定義しない場合、HTTP 401 Unauthorized応答が生成されます)。
  3. すべてがチェックアウトされ、有効なユーザーオブジェクトがあるので、それを渡します:next(null, user);これにより、successRedirect;がトリガーされます。

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

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

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

EDIT:また、(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);
});
_
156
robertklep

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

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/

18
cpoole

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

2