【问题标题】:Email verification with one click link通过一键链接进行电子邮件验证
【发布时间】:2017-12-04 00:12:43
【问题描述】:

我做了这个代码,它帮助我验证我的注册电子邮件。首先,我在注册时针对每个用户在我的数据库中设置一个秘密令牌。然后我将该秘密令牌发送到带有消息的个人电子邮件,并将此令牌粘贴到用户验证页面进行验证。

这是我的注册 API:

router.post('/register', (req, res) => {

    const secretToken = randomstring.generate();
    var name = req.body.name;
    var username = req.body.username;
    var email = req.body.email;
    var password = req.body.password;
    var cpassword = req.body.cpassword;

   

   req.checkBody('name','Name is required').notEmpty();
   req.checkBody('email','Email is required').notEmpty();
   req.checkBody('email', 'Email is not valid').isEmail();
   req.checkBody('username','username is required').notEmpty();
   req.checkBody('password','password is required').notEmpty();
   req.checkBody('cpassword','passwords do not match').equals(req.body.password);
   var errors = req.validationErrors();
   if(errors)
   {
       res.render('register', {
           errors: errors
       });
   }
   else
   {
    User.findOne({email: req.body.email}, function(err, existingUser)
    {
            if(existingUser)
            {
                req.flash('error_msg', 'Email address already exits try different one!!');
                res.redirect('/users/register');
                console.log("In db save body");
            }
            else
            {
            var newUser = new User(
                {
                    name:name,
                    email:email, 
                    username:username,
                    password:password,
                    secretToken:secretToken,
                    active: false
                });
      
            User.createUser(newUser, (err,user) => {
                  if(err) throw err;
                  console.log(user);
            });
            
            //Composing email
            const html = `Hi there
            <br/>
            Thank you for registering!
            <br/><br/>
            Please verify your email by typing following token:
            <br/>
            Token : <b>${secretToken}<b>
            <br/>
            On the following page : 
            <a href="https://login-app-passport.herokuapp.com/users/verify">https://login-app-passport.herokuapp.com/users/verify</a>
            <br/><br/>
            Have a good day!`;

            mailer.sendEmail('admin@teamfly.com',email,'Please verify your email',html);
            req.flash('success_msg','Please check your email');
            res.redirect('/users/login');
          }


    });
    }
    

});

当我将我的秘密令牌放入我的数据库作为 secretToken 更新为 null 和活动状态 false 为 true。

这是我的验证 API:

router.route('/verify')
.get( (req, res) => {
    res.render('verify');
})
.post( (req, res, next) => {
    
        const {secretToken} = req.body;
        const user = User.findOne({'secretToken' : secretToken.trim()}).then((user) => {
            if(!user)
            {
                req.flash('error_msg', 'No user found');
                res.redirect('/users/verify');
                return;
            }
        
            user.active = true;
            user.secretToken = '';
            user.save();
         
            
           
        
            req.flash('success_msg','Thank you.You can now login');
            res.redirect('/users/login');
        });
            

    
        

        

    
    
});

我的问题是我想发送一个包含秘密令牌的链接,当我单击该链接时,我希望我的数据库自动更新(secretToken 为 null,活动状态为 true)并将我重定向到登录路径。我不想从电子邮件中复制秘密令牌并将其粘贴到验证页面。

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    secretToken 放在验证网址上。用户单击该 url(或将 url 复制/粘贴到浏览器中),从 url 中提取令牌并更新您的数据库。

    确保secretToken 仅包含网址安全字符,否则您需要对其进行网址编码。

    电子邮件信息:

    <a href="https://login-app-passport.herokuapp.com/users/verify/${secretToken}">https://login-app-passport.herokuapp.com/users/verify/${secretToken}</a>
    

    我不知道您使用的是哪个路由器,但您只需要一个 GET /verify/:token,不需要 POST 路由。从.params 中提取令牌(或查询字符串,如果您愿意,请相应地更新 url)。

    router.route('/verify/:secretToken')
    .get( (req, res) => {
        const {secretToken} = req.params;
        const user = User.findOne({'secretToken' : secretToken.trim()}).then((user) => {
            if(!user)
            {
                req.flash('error_msg', 'No user found');
                res.redirect('/users/verify-error');
                return;
            }
    
            user.active = true;
            user.secretToken = '';
            user.save();
    
            req.flash('success_msg','Thank you.You can now login');
            res.redirect('/users/login');
        });
    

    【讨论】:

    • 显示此错误类型错误:无法匹配“未定义”或“空”。在 router.route.get (F:\nodeJS_Practice\node_project_passport\routes\users.js:184:35)
    • 这一行错误 const {secretToken} = req.body.params;
    • 应该是const {secretToken} = req.params;
    【解决方案2】:

    只需使用您填写的令牌并在找到用户后更新的 url 参数:

    您的验证部分:

    router.route("/verify/:token").get((res, req) => {
        const token = req.params.token;
        User.findOneAndUpdate({secretToken: token}, {$set: {secretToken:null, active:true}}, (err, user) => {
            if (!err) res.redirect("/users/login")
        });
    });
    

    您的注册部分:

    const verificationLink = `https://login-app-passport.herokuapp.com/verify/${token}`;
    const html = `Hi there
    <br>
    Thank you for registering!
    <br><br>
    Please verify your email by following this link:
    <br>
    <b>${verificationLink}<b>
    <br>
    Have a good day!`;
    

    【讨论】:

      猜你喜欢
      • 2011-03-15
      • 1970-01-01
      • 2011-03-21
      • 2018-09-14
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 2011-03-06
      • 1970-01-01
      相关资源
      最近更新 更多