节点 - Passport Auth - Authed Post Route在表单提交时挂起

时间:2013-07-24 17:19:17

标签: node.js mongodb authentication express passport.js

这很奇怪。我的快递应用程序的Im Passport的“本地策略”,我遇到了一个奇怪的问题。

基本上,我有三条路线。每个人都有一个auth检查。

app.get('/admin', authenticatedOrNot, adminRoute.index);
app.get('/admin/new', authenticatedOrNot, adminRoute.newpost);
app.post('/admin/new', authenticatedOrNot, adminRoute.create);

authenticatedOrNot方法很简单:

var authenticatedOrNot = function(req, res, next){
    if(req.isAuthenticated()){
        next();
    }else{
        res.redirect("/login");
    }
}

非常适合登录管理区域,并检查用户是否已登录,但是当我将表单提交到'/ admin / new'Post路由时,浏览器会挂起。即使使用console.log,控制台也不会发生任何事情:

exports.create = function(req, res){
    console.log(req);
        // Database logic here
        res.redirect('/admin');
}

我似乎无法让它发挥作用。它只是挂起,最终失败了。浏览器控制台只是在网络请求中说“待定”。

我已经尝试从发布路径和同样的问题中删除'authenticatedOrNot'方法,但如果我删除所有三个方法就可以正常工作。

我很难过。

任何帮助人?还有其他人遇到过这个吗?

2 个答案:

答案 0 :(得分:1)

我有一个与此非常相似的问题,所以我发布这个以防万一。 问题似乎是我在护照​​函数中有另一个函数定义,这阻止了调用done处理程序。我认为那是问题所在,因为当我更改函数参数名称时,事情就开始起作用了。

事后我认为错误是显而易见的,但由于我是节点的新手,我对函数,回调,闭包等等仍然有点不确定。我也有这样的印象:节点约定始终是使用这些参数名称(错误,完成,接下来),并且有一些与之相关的魔法。我猜不是。请在这一点上教育我。

无论如何,我使用的护照本地策略是我从教程中复制的(http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local)。 该教程使用了mongo,但我决定切换到postgresql。所以我使用了https://github.com/brianc/node-postgres-pure中的pg.js模块,并使用了提供的示例代码。

在我最初将pg.js示例代码复制并粘贴到护照教程中之后,这是代码的相关部分:

//错误代码

passport.use('local', new LocalStrategy({
    // by default, local strategy uses username and password, we will override with email
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { 
    pg.connect(configDB.connectionString, function(err, client, done) {
        if (err) {
            return console.error('could not connect to postgres', err);
        }
        client.query('select email, password_hash from admin_user where email = $1', [email], function(err, result) {

            // check password against db, and then try to call passports done callback
            return done(null, userModel); // this actually invokes the pg.connect done callback

        });
    });
}));

所以当这个运行时,在回到/ login的帖子上,对done的调用会调用pg.connect完成,而不是护照完成。

//好吗?工作代码

function(req, email, password, done) { 

    pg.connect(configDB.connectionString, function(err, client, connect_done) {
        if (err) {
            return console.error('could not connect to postgres', err);
        }
        client.query('select email, password_hash from admin_user where email = $1', [email], function(err, result) {
            connect_done() // free up postgres connection, which I should have been doing before
            // check password against db, and then
            return done(null, userModel); // invoke passport's done callback

        });
    });
}));

此代码现在正在为我工​​作(除非我错误地复制了某些内容)。

答案 1 :(得分:0)

当您分割越来越多时,对这种麻烦的诊断变得更加容易......最好的方法是使用一些嗅探器(内置Chrome,Firefox,Opera或独立)并准确获取您发送到的标头你的服务器。这非常有用,因为您可以将问题本地化到前端应用程序(例如<form acton="/admin/new" - 错误类型)或后端。

让我们道歉你的标题是好的,你在/admin/new路线发送完全POST。由于您的console.log( req );没有生效,显然应用程序没有达到这一点。这可能是因为authenticatedOrNot挂起或因为adminRoute.create没有正确实例化。

正如我所见,

authenticatedOrNot可能会挂起/login重定向,因为您没有提供处理此路线的方式。

adminRoute.create可能会导致一些问题,具体取决于您将其附加到应用中的方式。

因此,在简历中,我需要查看更多代码来解决问题。