В процессе реализации регистрации пользователя нам необходимо научиться отправлять электронное письмо для активации. Теперь я хотел бы показать вам, как я завершаю активацию пользователя, отправляя электронное письмо.

Конкретный процесс выглядит следующим образом:

  • Отправка ссылок для активации:

1. Пользователи регистрируются и отправляют регистрационную информацию.

2. Сохраните информацию о пользователе, сгенерируйте код активации и установите срок действия активации.

3. Отправка письма активации, включая код активации.

  • Обработка ссылок для активации

1. Пользователи нажимают, чтобы активировать ссылку в письме, которое содержит код активации.

2. Мы получили запрос на эту ссылку и код активации.

3. Узнаем код активации, соответствующий пользователю, и проверяем, не истек ли срок действия кода активации.

4. Если пользователь не найден или срок действия кода активации истек, код активации недействителен. Если все нормально, активируйте соответствующего пользователя.

Для реализации механизма активации пользователя нам необходимо создать модель пользователя:

Активный: (логический) определяет состояние активации пользователя.

ActiveToken: код активации, он будет отправлен на почтовый ящик пользователя;

ActiveExpires: срок действия кода активации

var UserSchema = new Schema({
    username: String,
    password: String,
    title: String,
    description: String,
    active: {
        type: Boolean,
        default: false
    },
    activeToken: String,
    activeExpires: Date,
});

Обратите внимание, что здесь нам нужен модуль импорта nodemailer, мы можем использовать следующий код для реализации модуляции отправки электронной почты. Целью кода является отправка почты только с одним утверждением.

// file: utils/mailer.js
var _ = require('lodash');	
var nodemailer = require('nodemailer');

var config = {
    host: 'smtp.126.com',
    port: 25,
    auth: {
        user: '[email protected]',
        pass: 'yourpassword'
    }
};
    
var transporter = nodemailer.createTransport(config);

var defaultMail = {
    from: 'Me <[email protected]>',
    text: 'test text',
};

module.exports = function(mail){
    // use default setting
    mail = _.merge({}, defaultMail, mail);
    
    // send email
    transporter.sendMail(mail, function(error, info){
        if(error) return console.log(error);
        console.log('mail sent:', info.response);
    });
};

Когда пользователь регистрируется, мы сначала сохраняем информацию о пользователе (имя пользователя, зашифрованный пароль), затем генерируем код активации и сохраняем его. Одновременно мы отправляем код активации на почтовый ящик пользователя.

var mailer = require('./utils/mailer');
var crypto = require('crypto');

router.post('/register', function(req, res, next){
  User.register(new User({username: req.body.username}), 
    req.body.password,
    function (err, user) {
    
        ...
        // Generate 20 bit activation code, ‘crypto’ is nodejs built in package.
        crypto.randomBytes(20, function (err, buf) {
            
            // Ensure the activation code is unique.
            user.activeToken = user._id buf.toString('hex');
            
            // Set expiration time is 24 hours.
            user.activeExpires = Date.now() + 24 * 3600 * 1000;
                var link = 'https://locolhost:3000/account/active/'
                           + user.activeToken;
                  
                // Sending activation email
                mailer.send({
                    to: req.body.username,
                    subject: 'Welcome',
                    html: 'Please click <a href="' + link + '"> here </a> to activate your account.'
                });

                // save user object
                user.save(function(err, user){
                    if(err) return next(err);
                    res.send('The activation email has been sent to' + user.username + ', please click the activation link within 24 hours.');
                });
            });
        });
    });
  });

Обратите внимание, что ссылка для активации в письме: / Account / active / ‹activeToken›. Следовательно, нам необходимо реализовать соответствующую маршрутизацию и контроллер.

router.get('/active/:activeToken', function (req, res, next) {

    // find the corresponding user
    User.findOne({
        activeToken: req.params.activeToken,
        
        // check if the expire time > the current time       activeExpires: {$gt: Date.now()}
    }, function (err, user) {
        if (err) return next(err);
        
        // invalid activation code
        if (!user) {
            return res.render('message', {
                title: 'fail to activate',
                content: 'Your activation link is invalid, please <a href="/account/signup">register</a> again'
            });
        }

        // activate and save
        user.active = true;
        user.save(function (err, user) {
            if (err) return next(err);

            // activation success
            res.render('message', {
                title: 'activation success!',
                content: user.username + 'Please <a href="/account/login">login</a>'
            })
        });
    });
});

На этом мы завершили активацию учетной записи.

Поговорим подробнее о властном контроле :

Некоторые контроллеры (или промежуточное ПО) требуют, чтобы пользователь вошел в систему (например, настройки учетной записи, управление блогом), и даже требуют, чтобы у пользователя была определенная личность.

Нам нужно иметь промежуточное ПО с именем auth-required.js

// file: utils/auth-required.js

module.exports = function(req,res,next){
    if(req.user && req.user.active) return next();
    return res.redirect('/account/login?next=' + req.originalUrl);
  }
};

Мы используем это промежуточное ПО, например:

var authRequired = require('./utils/auth-required.js');

// When URL matches /home, run the two middleware chains.
app.use('/home', authRequired, function(req, res, next){

    // you can safely use req.user here.
});