javascript 在passport.js 中带有令牌的验证电子邮件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28847491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:38:48  来源:igfitidea点击:

Verification email with token in passport.js

javascriptnode.jstokenpassport.jspassport-local

提问by Makromat

I just looking for solution which makes verification email with token for my local autentification in passport.js Is there some plugin or component for node which can make me verification easyer? Or I have to do it myself?

我只是在寻找使用令牌生成验证电子邮件的解决方案,用于我在passport.js 中的本地身份验证 是否有一些插件或组件可以让我更轻松地验证节点?还是我必须自己做?

My controller

我的控制器

exports.postSignup = function(req, res, next) {
  req.assert('email', 'Email is not valid').isEmail();
  req.assert('password', 'Password must be at least 4 characters long').len(4);
  req.assert('confirmPassword', 'Passwords do not match').equals(req.body.password);

  var errors = req.validationErrors();

  if (errors) {
    req.flash('errors', errors);
    return res.redirect('/signup');
  }

  var user = User.build({
    email: req.body.email,
    password: req.body.password,
  });

  User
  .find({ where: { email: req.body.email } })
  .then(function(existingUser){
    if (existingUser) {
      req.flash('errors', { msg: 'Account with that email address already exists.' });
      return res.redirect('/signup');
    }

    user
    .save()
    .complete(function(err){
      if (err) return next(err);
      req.logIn(user, function(err){
        if (err) return next(err);
        res.redirect('/');
      });
    });
  }).catch(function(err){
    return next(err);
  });
};

Thanks for any opinion!

感谢您的任何意见!

回答by Tom

Implementing this yourself is pretty straightforward.

自己实现这一点非常简单。

The pseudocode:

伪代码:

//A user registers
    //User is stored along with a random token string and a variable set to false
    //User is sent a verification email

//Verification email has a link with the random token and a unique ID for that user

//Link goes to a route that takes the token as a parameter


//Match the user and the random token

//If they match - change a variable to verified

The package I use to generage the random string is: https://www.npmjs.com/package/randomstring

我用来生成随机字符串的包是:https://www.npmjs.com/package/randomstring

Local signup strategy

本地注册策略

passport.use('local-signup', 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) {
        // asynchronous
        // User.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
            User.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) {
                    console.log('that email exists');
                    return done(null, false, req.flash('signupMessage', email + ' is already in use. '));

                } else {
                    User.findOne({'local.username': req.body.username}, function (err, user) {
                        if (user) {
                            console.log('That username exists');
                            return done(null, false, req.flash('signupMessage', 'That username is already taken.'));
                        }

                        if (req.body.password != req.body.confirm_password) {
                            console.log('Passwords do not match');
                            return done(null, false, req.flash('signupMessage', 'Your passwords do not match'));
                        }

                        else {
                            // create the user
                            var newUser = new User();

                            var permalink = req.body.username.toLowerCase().replace(' ', '').replace(/[^\w\s]/gi, '').trim();

                            var verification_token = randomstring.generate({
                                length: 64
                            });


                            newUser.local.email = email;

                            newUser.local.password = newUser.generateHash(password);

                            newUser.local.permalink = permalink;

                            //Verified will get turned to true when they verify email address
                            newUser.local.verified = false;
                            newUser.local.verify_token = verification_token;

                            try {
                                newUser.save(function (err) {
                                    if (err) {

                                        throw err;
                                    } else {
                                        VerifyEmail.sendverification(email, verification_token, permalink);
                                        return done(null, newUser);
                                    }
                                });
                            } catch (err) {

                            }
                        }
                    });
                }
            });
        });
    }));

I use a combination of /permalink/random-token for the verification URL

我使用 /permalink/random-token 的组合作为验证 URL

The route should look like this:

路线应如下所示:

app.get('/verify/:permaink/:token', function (req, res) {
        var permalink = req.params.permaink;
        var token = req.params.token;

        User.findOne({'local.permalink': permalink}, function (err, user) {
            if (user.local.verify_token == token) {
                console.log('that token is correct! Verify the user');

                User.findOneAndUpdate({'local.permalink': permalink}, {'local.verified': true}, function (err, resp) {
                    console.log('The user has been verified!');
                });

                res.redirect('/login');
            } else {
                console.log('The token is wrong! Reject the user. token should be: ' + user.local.verify_token);
            }
        });
    });