【问题标题】:Update or add fields in passport.js local-strategy?在 passport.js 本地策略中更新或添加字段?
【发布时间】:2015-01-07 00:29:48
【问题描述】:

我到处都是文档,但我似乎找不到更新凭据的方法。

这是我通过分析代码得到的。

passport.deserializeUser(function(id, done) {
    AppUser.findById(id, function(err, user) {
        done(err, user);
    });
});

DeserializeUser 看起来很有用,但我不知道如何使用它来更新或添加字段?

我试图破解并复制登录中的逻辑并理解它。

passport.use('local-update', new LocalStrategy({
    usernameField : 'username',
    passReqToCallback : true
},
function(req, username, done) {

    console.log(req)
    // asynchronous
    // AppUser.findOne wont fire unless data is sent back
    // process.nextTick(function() {

    //     // find a user whose email is the same as the forms email
    //     // we are checking to see if the user trying to login already exists
    //     AppUser.findOne({ 'local.email' :  email }, function(err, user) {
    //         // if there are any errors, return the error
    //         if (err)
    //             return done(err);

    //         // check to see if theres already a user with that email
    //         if (!user) {
    //             //return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
    //             return done(null, false);
    //         } else {

    //             // if there is a user with that email
    //             // create the username
    //             var updateUser = new AppUser();

    //             // set the user's local credentials
    //             newUser.local.email    = email;
    //             newUser.local.password = newUser.generateHash(password);

    //             // save the user
    //             newUser.update(function(err) {
    //                 if (err)
    //                     throw err;
    //                 return done(null, newUser);
    //             });
    //         }

    //     });    

    // });

}));

然后在表单提交上我这样做了。

app.post('/profile', passport.authenticate('local-update', {
    successRedirect : '/', // redirect to the secure profile section
    failureRedirect : '/signup' // redirect back to the signup page if there is an error
    //failureFlash : true // allow flash messages
}));

这会导致重定向失败。

因为没有响应所以不行,但是我需要在mongoDB中找到模型。我试图先在控制台中查看 req,这样也许我可以看到如何找到模型,但没有任何显示。

上面显然是 HACKISH 代码,但这是我能做的最好的。我需要一个具体的答案,我确信它很简单,我在文档中错过了它!

编辑:这里的想法是当用户注册/登录时,他们会提供电子邮件。用户登录并创建帐户后,他们可以创建用户名。

编辑:所以我不知道如何使用护照提出更新请求,但在我的路由器中我有这样的东西。

app.post('/', function(req, res) {
    if (req.user) {
        AppUser.findOne({ _id: req.user.id }, function (err, user) {
            user.local.username  = req.body.username;
            user.save(function(err) {
                if (err){
                    console.log('Error')
                } else {
                    console.log('Sucess')
                }
            });
        });
    }
});

唯一的问题是浏览器的默认操作,它提交表单并保持页面无休止地重新加载。但它确实更新了我的 mongodb 模型。我必须添加到 Schema,并且必须在我的护照注册逻辑中添加该属性。

但我可以将此逻辑添加到我的客户端代码中,然后将 POST 方法放入主干中,这应该可以工作!

【问题讨论】:

  • 您的意思是req.body 不包含您需要的字段?
  • 它应该给我我需要的东西,但我无法让该请求响应服务器端 CLI 控制台,这意味着一旦它出现在控制台中,我现在就可以访问它了吨。总的来说,我很新而且很困惑,但是当我可以返回回调一个 successRedirect 时,我会好很多。
  • 它还需要一些 mongodb 查询我尝试了类似 AppUser.update({'local.email' : 'myemail@gmail.com'}, { $set: { "local.email": "Warner" } }); 的静态内容,但如果回调返回 false,则查询不会执行,认为 function(req, username, done) 中的任何内容无用。我为这个特定实例设置 localStrategy 的方式显然有问题。
  • 我换了my answer,你需要这样的东西吗?
  • 如果浏览器卡在“无休止的重新加载”中,可能是因为您没有发送任何响应。要解决这个问题,您可以尝试使用 res.send(200)res.send(403) 而不是 console.log('Success')console.log('Error') 。是这个问题吗?

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


【解决方案1】:

在这种情况下,您可以添加 callback array 作为 Express 路由的参数。

我想您可以将验证处理程序更改为:

function(req, username, done) {
    //perform here only the validations you need to let the login pass
    if (validationSuccess) {
        done();
    } else {
    done('an error occured');
    }
}

所以,假设这个函数将成功验证用户凭据,你可以编写另一个:

function doSomethingAfter(req, res, next) {
    //do anything else you need here
    //e.g.
    SomeModel.create(req.body.username);
    //the response is available here
    res.send('Everything ok');
}

最后,你可以编辑你的路由功能

app.post('/profile', [passport.authenticate('local-update', {
    failureRedirect : '/signup' // redirect back to the signup page if there is an error
}), doSomethingAfter]);

这样,您可以在请求被正确验证后执行身份验证并进行任何您想要的操作。如果您需要添加更多函数,则必须将它们添加到数组中并在每个函数上调用next()

希望对你有帮助。

【讨论】:

  • 感谢您的帮助,但我不确定我是否理解如何整合它。我相信这可能是一个很好的解决方案。看看我在上面的 OP 中想出了什么。
  • 我的回答是关于快递的行为。当您使用app.post('/foo', handler) 添加端点时,处理程序是一个使用reqresnext 参数的函数。 next 参数可用于异步迭代一组函数(每个函数都采用相同的参数),方法是在函数内部调用 next() 以快速调用下一个函数。当您使用 passport.authenticate 时,该调用返回一个接受 reqresnext 参数的函数,因此您可以将它作为数组的成员(而不是我的 handler 参数)传递,并添加作为成员的另一个功能。
  • 1+ 的解释,谢谢你,但这是有道理的,但对我个人来说,我所使用的更容易理解。我没有看到任何问题并且感觉很干净。这是一个很好的解决方案,令人惊奇的是,您可以通过多种方式完成一件事。
猜你喜欢
  • 2014-11-12
  • 2015-05-22
  • 2018-11-10
  • 2015-01-01
  • 2017-09-18
  • 1970-01-01
  • 2013-08-29
  • 2020-12-26
  • 2014-03-20
相关资源
最近更新 更多