web-dev-qa-db-ja.com

Nodejs Passport認証コールバックが呼び出されない

Nodejs Passportを使用して、次のコードを使用してエラー条件が発生したときに何が起こるかをテストしました。

_passport.use(new LocalStrategy(
  function(username, password, done) {
    // asynchronous verification, for effect...
    process.nextTick(function () {
      findByUsername(username, function(err, user) {
    console.log('in auth function');
      return done('errortest');
        if (err) { return done(err); }
        if (!user) {
          return done(null, false, { message: 'Unknown user ' + username });
        }
        if (user.password != password) {
          return done(null, false, { message: 'Invalid password' });
        }
        return done(null, user);
      })
    });
  }
));

app.get('/logintest', function(req, res, next) {
console.log('before authenticate');
  passport.authenticate('local', function(err, user, info) {
console.log('authenticate callback');
    if (err) { return res.send({'status':'err','message':err.message}); }
    if (!user) { return res.send({'status':'fail','message':info.message}); }
    req.logIn(user, function(err) {
      if (err) { return res.send({'status':'err','message':err.message}); }
      return res.send({'status':'ok'});
    });
  })(req, res, next);
});
_

ルートを使用する/ logintest?username = bob&password = sコンソールに表示されると予想されていた「認証前」、「認証関数内」、「認証コールバック」の最初の2つと「エラーテスト」、「エラーテストブラウザに「」が表示されます。

私もreturn done({'message':'test'});を試しましたが、「[object Object]」がコンソールとブラウザに表示されました。

これは正しく機能していないのですか、それとも何か不足していますか?

編集:Jared Hansonの応答に従って、このエラーハンドラー関数を3番目の引数としてapp.get()に追加すると、エラーをキャッチして適切なjsonを返すことができます。

_...
    })(req, res, next);
  },
  function(err, req, res, next) {
    // failure in login test route
    return res.send({'status':'err','message':err.message});
  });
_
22
KevinVictor

あなたはそれを完全に理解し、意図したとおりに機能しています。

エラーが発生した場合、Passportはすぐにそのエラーでnext()を使用します。エラーをカスタム処理する場合は、エラー処理ミドルウェア(詳細: http://expressjs.com/guide/error-handling.html )を使用できます。

カスタムコールバックは、主に認証の成功または失敗(user == false)を処理するために使用されます。上記のエラー処理ミドルウェアのために、DB接続などのエラーはコールバックに渡されません。私はこれを変更することを検討しましたが、やむを得ない理由を見つけていません。ただし、上記でカバーされていないユースケースがある場合は、お知らせください。

18
Jared Hanson

bodyparser.json()が問題を引き起こしていました。次のように、ルートごと(特にパスポートルート上)に設定することで修正しました。

app.post('/login', bodyParser.urlencoded({ extended: true }), function (req, res, next) {
          passport.authenticate('local', function (err, user, info) {
               if (err) { return next(err) }
               if (!user) {
                    console.log('bad');
                    req.session.messages = [info.message];
                    return res.redirect('/login')
               }
               req.logIn(user, function (err) {
                    console.log('good');
                    if (err) { return next(err); }
                    return res.redirect('/');
               });
          })(req, res, next);
     });
6
mitch

私も同じ問題を抱えていました。次に置く、

const bodyParser=require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
2
dilanSachi