Passport-local返回400错误,从不查询数据库

时间:2014-04-02 03:04:57

标签: node.js passport.js passport-local

我正在尝试在我的node.js应用中使用passport.js来验证使用MongoDB的用户。我从未取得过成功。

在帖子中,我发送“email”:“email@gmail.com”,         “密码”:“测试”

var passport = require('passport')
   , LocalStrategy = require('passport-local').Strategy;


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

passport.use(new LocalStrategy({
      emailField: 'email',
      passwordField: 'passw',
   },
function (emailField, passwordField, done) {
   process.nextTick(function () {
      db.collection(users, function (error, collection) {
         if (!error) {
            collection.findOne({
               'email': emailField,
               'password': passwordField
            }, function (err, user) {
               if (err) {
                  return done(err);
               }
               if (!user) {
                  console.log('this email does not exist');
                  return done(null, false);
               }
                  return done(null, user);
            });
         } else {
            console.log(5, 'DB error');
         }
      });
   });
}));

在MongoDB'用户'集合中:

{
    "_id": {
        "$oid": "533b5283e4b09d8a1148b4c4"
    },
    "email": "email@gmail.com",
    "password": "test"
}

也许我没有正确连接数据库,我不确定。

另外,当我在整个函数中记录所有内容时,我没有得到任何日志。我只是得到

 POST /login 302 7ms - 39b  
 GET /fail 404 3ms

任何建议都将不胜感激。我想我可能会遗漏一些东西,但我不确定如何构建这个。在我写入数据库的另一个函数中,我必须使用:

var uristring = 
process.env.MONGOLAB_URI || 
process.env.MONGOHQ_URL || 
'mongodb://<myurlhere>';

mongo.connect(uristring, function (err, db) {

以下是更新后的代码

要求:

   , passport = require('passport')
   , LocalStrategy = require('passport-local').Strategy;

使用这些:

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ secret: 'keyboard cat'}));
app.use(logfmt.requestLogger());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);

// User authentication passport

passport.use(new LocalStrategy(
    {
        usernameField: 'email',
        passwordField: 'passw',
    },
    function (userId, password, done) {
        // removed process.nextTick
        console.log('Hey! no more 400 error!');
        db.collection(users, function (error, collection) {
            if (!error) {
                collection.findOne({
                    'email': userId,
                    'password': password
                }, function (err, user) {
                    if (err) {
                        return done(err);
                    }
                    if (!user) {
                        console.log('this email does not exist');
                        return done(null, false);
                    }
                    return done(null, user);
                });
            } else {
                console.log(5, 'DB error');
            }
        });
    } 
));

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(user, done) {
  done(null, user);
});

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

此帖子在发布到/ login时总是给我POST /login 400 10ms。我所有其他路线都可以正常工作。

2 个答案:

答案 0 :(得分:17)

1)可怕的HTTP 400错误

如果未设置用户名和/或密码,Passport会抛出HTTP 400错误。

请参阅第75行的来源,其中Strategy.prototype.authenticate会引发'missing credentials'错误。

2)诊断原因

在你的代码中,你有块:

passport.use(new LocalStrategy({
      emailField: 'email',
      passwordField: 'passw',
   },

但护照不承认emailField。回到source code,我们看到护照正在寻找:

this._usernameField = options.usernameField || 'username';
this._passwordField = options.passwordField || 'password';

这就是在这种特定情况下抛出HTTP 400的原因。

4)解决问题

我已将原始代码编辑为我认为比原始代码更有效(更好)。编辑时我取消了process.nextTick并重命名了一些内容。我希望你是一个宽容的人。 :)

passport.use(new LocalStrategy(
    {
        usernameField: 'email',
        passwordField: 'passw',
    },
    function (userId, password, done) {
        // removed process.nextTick
        console.log('Hey! no more 400 error!');
        db.collection(users, function (error, collection) {
            if (!error) {
                collection.findOne({
                    'email': userId,
                    'password': password
                }, function (err, user) {
                    if (err) {
                        return done(err);
                    }
                    if (!user) {
                        console.log('this email does not exist');
                        return done(null, false);
                    }
                    return done(null, user);
                });
            } else {
                console.log(5, 'DB error');
            }
        });
    } 
));

5)一些结束语:

  • 您还可以编辑表单输入属性以匹配护照的预期默认值。有关指导,请参阅passport documentation
  • 我无法保证MongoDB调用能够正常工作,但这应该让你通过HTTP 400.如果数据库调用有问题,那几乎肯定是一个新问题,因为涉及到一组不同的代码和模块。
  • 使用护照时,值得访问项目GitHub页面并阅读源代码。源代码中经常有评论说:(a)不在其他文档中,或者(b)与他们描述的代码很接近......所以即使你不是编码大师,也要为你澄清事情。

答案 1 :(得分:1)

这最终成为Postman的一个问题(我已经多次使用过了很多次而没有问题)。

一旦我使用了真正的html表单,它运行正常。也许是标头的东西?