【问题标题】:Passport-local returns 400 error, never queries databasePassport-local 返回 400 错误,从不查询数据库
【发布时间】:2015-01-06 23:52:13
【问题描述】:

我正在尝试在我的 node.js 应用程序中使用 passport.js 来使用 MongoDB 对用户进行身份验证。我从来没有成功过。

在帖子中,我发送“电子邮件”:“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。我所有其他路线都可以正常工作。

【问题讨论】:

  • 您的代码是在一个文件中还是分成模块?我问是因为你调用事物的顺序很重要。另外,您是否出于特定原因在代码中留下了process.nextTick?我相信在示例代码中可以“模拟”数据库调用的延迟,但实际上并不需要。
  • 不,我刚刚启动了这个应用程序,目前这个功能在 app.js 中。我计划在身份验证工作后打破使其更加模块化。
  • 我尝试了很多东西。目前我得到一个 404。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);});
  • 我无法弄清楚如何在评论中执行代码块。 4个空格不起作用。 backtics 工作,但不要添加新行。
  • 您在发布到 /login 时收到 404?

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


【解决方案1】:

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。如果数据库调用有问题,那几乎肯定是一个新问题,因为涉及到一组不同的代码和模块。李>
  • 使用passport时,值得访问项目GitHub页面并阅读源代码。源代码中经常有 cmets (a) 不在其他文档中,或者 (b) 与他们描述的代码很接近……所以即使您不是编码专家或其他什么,事情也会为您澄清。

【讨论】:

  • 我仍然获得 400。如果我能超过 400,我可能会解决这个问题。除了 400 之外,我仍然无法获得任何日志。我已经用我的更改更新了原始帖子。 POST /login 400 10ms
  • 我发帖到localhost:3000/login。我所有的其他路线都有效。我正在发送电子邮件和密码
  • 我已经将您发布的所有内容复制到一个单页应用程序中,该应用程序基于使用 express 和 mongo 的本地护照示例。我唯一能达到 400 的情况是登录表单中的属性与护照所期望的不匹配。对不起,我不能做更多。如果你弄明白了,我很想知道发生了什么。
  • 你是最棒的@MatthewBakaitis
  • 对我来说,问题是我没有使用正文解析器,因此我的req.body 未定义。我以为passport-local 处理了这个,但事实并非如此。只需要在body-parser 上做一个app.use
【解决方案2】:

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

一旦我使用了真正的 html 表单,它就可以正常工作。也许是标题的事情?

【讨论】:

  • 我在使用 Postman 时也遇到过类似的问题。即使打开了拦截器扩展,它似乎也没有维护任何会话持久性的概念(通过 cookie)。
  • 邮递员也有同样的问题。最初我使用表单数据发送数据并且它一直在工作。一旦我更新到最新的 express 和 connect 版本。我不得不使用 x-www-form-urlencoded
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 2014-03-24
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 2012-02-07
相关资源
最近更新 更多