5

我正在尝试在我的 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);
  });

POST /login 400 10ms发布到 /login 时,此代码总是给我。我所有的其他路线都很好。

4

2 回答 2

19

1) 可怕的 HTTP 400 错误

当未设置用户名和/或密码时,Passport 会引发 HTTP 400 错误。

请参阅第 75 行附近的源代码,其中Strategy.prototype.authenticate会引发“缺少凭据”错误。

2) 诊断原因

在您的代码中,您有以下块:

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

但是emailField护照不承认。回到源代码,我们看到护照正在寻找:

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) 一些结束语:

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

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

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

于 2014-04-20T14:23:40.303 回答