仅在电子邮件验证后才使用passport.js对新用户进行身份验证

时间:2019-09-29 08:57:23

标签: javascript node.js mongodb mongoose passport.js

我将passport.jsmongoose(mongoDB)(和passport-local-mongoose)结合使用,以在节点/快速后端中创建和认证用户帐户。

我当前使用的策略是:

  • 用户填写一个注册表单,其中包括username输入type="email" name="username"password输入name='password'(还有其他内容) *
  • 用户提交表单。
  • 将新用户添加到配置文件架构let newUser = new Profile({username: req.body.username, ...})
  • 使用crypto.randomBytes(...)
  • 生成令牌
  • Profile.register(newUser, password)passport.authenticate用户和从上面的集合生成的集合令牌字段以及到期日期
  • 发送电子邮件给新用户,其URL包含其猫鼬_id和令牌(/u/${id}/is-valid/${token})。
  • 访问此网址时,Profile.findOne({_id: req.params.id})并检查令牌是否匹配,并且尚未过期
  • 如果没有,请将其发送到登录页面。

这种方法的问题在于,在同时调用Profile.registerpassport.authenticate时,会在用户验证电子邮件之前创建一个预先认证的帐户。

如何分离这两种方法,以便只有在验证用户的电子邮件地址后才能对用户进行身份验证?

以下是我如何称呼Profile.registerpassport.authenticate(作为async.waterfall([])的一部分:

Profile.register(user, pw)
    .then(response => {
        passport.authenticate("local")(req, res, function(err) {
            if (err) return callback(err);

            user.resetEmailToken = token;
            user.resetEmailExpires = Date.now() + 8.64e+7; // 1 day

            user.save(function(err) {
                callback(err, token, user);
            });
        });
    })
    .catch(err => {
        return callback(err);
    });

我想像上面一样Profile.register,但是只有在检查了令牌后才passport.authenticate

这是我检查令牌的方式(通过电子邮件中包含的访问链接-/u/${id}/is-valid/${token}):

async verifyEmail(req, res, next){
    let user = await Profile.findOne({ '_id': req.params.id })

    if(!user) return res.redirect("back");

    if (user.resetEmailToken != req.params.token){
        req.flash("error", "Tokens don't match");
        return res.redirect("back");
    }

    if(user.resetEmailExpires < Date.now()){
        console.log("This date has expired", moment(user.resetEmailExpires).calendar());
        return res.redirect(`/signup?token-expired=${user.email}`);
    }

    user.isVerified = true;

    // Here is where I want to passport.authenticate() and redirect to their new profile

    user.save();

    return res.render('login', { user: user });
}

如果这不可能,那么我可以采取什么其他方法来实现这一目标?它必须是一种相当普遍的注册策略。

* 这有点像hacker.js假定使用用户名和密码(不是电子邮件)注册了

0 个答案:

没有答案
相关问题