未调用 Nodejs Passport 身份验证回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12217881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:14:56  来源:igfitidea点击:

Nodejs Passport authenticate callback not being called

node.jspassport.js

提问by KevinVictor

Using Nodejs Passport, I was testing out what happens when an error condition occurs using the following code:

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

Using the route /logintest?username=bob&password=s I expected to see in the console, "before authenticate" then "in auth function" then "authenticate callback" but it only shows the first two followed by "errortest", and "errortest" is displayed in the browser.

使用路由 /logintest?username=bob&password=s 我希望在控制台中看到“before authentication”然后“in auth function”然后“authenticate callback”但它只显示前两个后跟“errortest”和“errortest” " 显示在浏览器中。

I also tried return done({'message':'test'});and "[object Object]" was displayed in the console and in the browser.

我也试过return done({'message':'test'});在控制台和浏览器中显示“[object Object]”。

Is this not working properly or am I missing something?

这是工作不正常还是我错过了什么?

EDIT: As per Jared Hanson's response, adding this error handler function as the third argument to app.get() allows me to catch the error and return the appropriate json:

编辑:根据 Jared Hanson 的回复,将此错误处理函数作为第三个参数添加到 app.get() 允许我捕获错误并返回适当的 json:

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

采纳答案by Jared Hanson

You're understanding it perfectly, and its working as intended.

你完全理解它,它按预期工作。

If any error occurs, Passport immediately next()'s with that error. You can use error handling middleware (details: http://expressjs.com/guide/error-handling.html) if you want to handle that error in a custom manner.

如果发生任何错误,Passport 会立即出现next()该错误。如果您想以自定义方式处理该错误,您可以使用错误处理中间件(详细信息:http: //expressjs.com/guide/error-handling.html)。

Custom callbacks are primarily used to deal with authentication success or failure (user== false). Errors, like DB connectivity, etc, are not passed back to the callback, in favor of error handling middleware described above. I've considered changing this, but haven't found a compelling reason to. But, if you've got a use case that isn't covered by the above, let me know.

自定义回调主要用于处理身份验证成功或失败 ( user== false)。错误,如数据库连接等,不会传递回回调,有利于上述错误处理中间件。我已经考虑过改变这一点,但还没有找到一个令人信服的理由。但是,如果您有上述未涵盖的用例,请告诉我。

回答by mitch

bodyparser.json()was causing my problem, i fixed it by setting it per route (specifically on the passport route) like this:

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

回答by dilanSachi

I had the same problem. Then putting,

我有同样的问题。然后放,

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