Регистрация почтового ящика Node.js, активация, случаи входа в систему

Node.js Redis MongoDB

email-verify

Конкретный подробный код github
В дополнение к стороннему доступу для входа в систему текущая система входа в основном включает вход через SMS и вход по электронной почте.В соответствии с характеристиками текущей системы с реальным именем сейчас больше входов через SMS, но некоторые все еще используют входы по электронной почте.
Эта статья в основном посвящена связанным случаям входа в почтовый ящик. Говоря простым языком, пользователь использует почтовый ящик для регистрации. При успешной регистрации зарегистрированному пользователю будет отправлено электронное письмо для активации. Конечно, это электронное письмо имеет определенную своевременность. После активации пользователь может нормально использовать соответствующие функции.Если он не активирован, при входе в систему будет указано, что он не активирован, необходимо ли отправлять электронное письмо для его активации.

1. Используйте инструменты

  • node v8.5.0
  • mongodb
  • ioredis
  • postman

2. Структура проекта

项目结构图
Схема структуры проекта

На рисунке показано значение файлов ключей

3. Интерфейс регистрации пользователей

Когда пользователь регистрируется, сначала проверьте, переданы ли необходимые поля и соответствует ли пароль электронной почты спецификации, а затем проверьте, был ли зарегистрирован адрес электронной почты.При успешной регистрации пользователю будет отправлено электронное письмо для активации учетной записи. Содержимое отправленного электронного письма представляет собой ссылку. , которая содержит почтовый ящик пользователя и код. Код использует reid для установки времени истечения срока действия. (Статус пользователя равен 0, когда он не активирован, и 1, когда он активирован)
Маршруты, зарегистрированные в маршрутах, следующие:

 //user_regist
router.post('/user_regist', userCtrl.user_regist);

Часть кода, зарегистрированного в контроллерах, выглядит следующим образом:

     try {
        const user = await findUserAsyc({ 'useremail': user_email });//验证用户是否已注册
        if (user) {
            respondData.status = 10002;
            respondData.error = "邮箱已注册";
            return res.json(respondData);
        }
        //用户参数
        const userpassword = md5(user_password);
        const userInfo = {
            useremail: user_email,
            username: user_name,
            userpwd: userpassword,
            status: 0,
            create_time: Date.now('YYYY-MM-DD')
        };
        //新建用户
        console.log("newGuess.save userInfo-->" + JSON.stringify(userInfo));
        const newUser = new UserModel(userInfo);
        newUser.save(function (err, data) {
            if (err) {
                console.log("newGuess.save err-->" + JSON.stringify(err));
                respondData.status = "00001";
                respondData.error = "mongodb system error";
                return res.json(respondData);
            }
            console.log("newGuess.save data -->" + JSON.stringify(data));
            let userEmail = data.useremail;
            let sendEmail = sendUserEmail(userEmail);
            console.log("sendEmail:" + sendEmail);
            respondData.msg = "新用户注册成功 and 激活邮箱发送成功";
            return res.json(respondData);
        });
    } catch (error) {
        //错误处理
        console.log("controllers/UserController.js/user_regist error -->" + JSON.stringify(error));
        respondData.error = error;
        return res.json(respondData);
    }

Отправка части кода по электронной почте

    var config_email = {
        host: 'smtp.163.com',
        post: 25, // SMTP 端口
        //secureConnection: true, // 使用 SSL
        auth: {
            user: 'wangweifengyx@163.com',
            //这里密码不是qq密码,是你设置的smtp密码
            pass: 'wwf'
        }
    };
    var transporter = nodemailer.createTransport(config_email);

    var html = "<div>http://127.0.0.1:3000?code=" + code + "&account=" + cnd + "</div>";
    console.log(html);
    var data = {
        from: 'wangweifengyx@163.com', // 发件地址
        to: cnd, // 收件列表
        subject: 'Hello feng', // 标题

        //text: html // 标题 //text和html两者只支持一种
        html: html // html 内容
    };
    console.log(data);
    transporter.sendMail(data, function (err, info) {
        if (err) {
            return (err);
        }
        console.log(info.response);
        return (info.response);

    });

Используйте почтальона для имитации регистрации

postman模拟注册
ложная регистрация почтальона

Скриншот в это время просто захватывает сообщение, отправленное в почтовый ящик, идеально

Когда пользователь не активирован, статус=0 этого пользователя в базе данных, как показано на рисунке:
информация о пользователе базы данных

数据库用户信息
информация о пользователе базы данных

4. Активация почтового ящика пользователя

Почтовый ящик будет активирован нажатием ссылки в почтовом ящике. Если почтовый ящик не соответствует коду, будет возвращено сообщение о несоответствии почтового ящика. Когда срок действия кода истечет, будет возвращено сообщение об истечении срока действия кода. Когда пользователь активировал его, он сообщит пользователю, что он был активирован. Не активировать снова. , когда информация о пользователе не соответствует вышеуказанным условиям, он сообщит, что активация прошла успешно.
Маршруты, активированные в маршрутах, следующие:

//user_activation
router.get('/user_activation', userCtrl.user_activation);

Часть кода, зарегистрированного в контроллерах, выглядит следующим образом:

    try {
        let codeVal = await Jtoken(code);
        if (!codeVal) {
            respondData.error = "code失效,请重新发送邮件激活";
            return res.json(respondData);
        }
        let userinfo = JSON.parse(codeVal);
        if (userinfo.userEmail !== user_email) {
            respondData.error = "邮箱不正确";
            return res.json(respondData);
        }
        const user = await findUserAsyc({ 'useremail': user_email });//验证用户是否已注册
        if (user) {
            if (user.status === 0) {
                UserModel.update({ 'useremail': user_email }, { '$set': { status: 1 } }, function (err, results) {
                    if (err) {
                        console.log("UserModel.update err-->" + JSON.stringify(err));
                        respondData.status = "00001";
                        respondData.error = "mongodb system error";
                        return res.json(respondData);
                    }
                    respondData.msg = "邮箱激活成功";
                    return res.json(respondData);
                })
            } else if (user.status === 1) {
                respondData.msg = "此邮箱已经激活了哦,不要重复激活";
                return res.json(respondData);
            }
        }
    } catch (error) {
        //错误处理
        console.log("controllers/UserController.js/user_regist error -->" + JSON.stringify(error));
        respondData.error = error;
        return res.json(respondData);
    }

Используйте почтальон для имитации успешной активации

postman模拟激活成功
Активация имитации почтальона прошла успешно

Используйте почтальон для имитации сбоя кода активации
postman模拟激活code失效
сбой кода активации симуляции почтальона

Информация о пользователе базы данных при успешной активации
激活成功时数据库的用户信息
Информация о пользователе базы данных при успешной активации

5. Интерфейс входа пользователя

Когда пользователь не активирован, логин сообщит, что он не активирован и его нужно деактивировать.При активации информация будет нормальной и логин будет успешным.Если логин успешен, некоторая информация о пользователе будет возвращается, и токен будет добавлен.
Маршруты входа в маршруты маршрутизации следующие:

//user_login
router.post('/user_login', userCtrl.user_login);

Часть кода, зарегистрированного в контроллерах, выглядит следующим образом:

    try {
        const user = await findUserAsyc({ 'useremail': user_email });//验证用户是否已注册
        if (!user) {
            respondData.status = 10000;
            respondData.error = "邮箱未注册";
            return res.json(respondData);
        }
        const userverify = await findUserVerify(user_email,user_password);//验证用户
        if(!userverify){
            respondData.status = 10005;
            respondData.error = "邮箱或密码错误";
            return res.json(respondData);
        }
        console.log(userverify);
        if(userverify.status === 0){
            respondData.status = 10006;
            respondData.error = "邮箱未激活,请激活邮箱";
            return res.json(respondData);
        } else if(userverify.status === 1){
            const tokenexpiraton = 1800;
            const token = require('crypto').randomBytes(16).toString('hex');
            const tokenContent = {
                useremail: userverify.useremail,
                username: userverify.username
            };
            redis.set(token, JSON.stringify(tokenContent));
            redis.expire(token, tokenexpiraton);
            const userBackInfo = {};
            userBackInfo.token = token;
            userBackInfo.useremail = userverify.useremail;
            userBackInfo.username = userverify.username;
            userBackInfo._id = userverify._id;
            respondData.data.push(userBackInfo);
            respondData.msg = "登陆成功";
            return res.json(respondData);
        }    
    } catch (error) {
        //错误处理
        console.log("controllers/UserController.js/user_regist error -->" + JSON.stringify(error));
        respondData.error = error;
        return res.json(respondDaata);
    }

Когда логин не активирован

未激活登陆时
Когда логин не активирован

Когда логин активирован
已激活登陆时
Когда логин активирован

6. Последующие действия

На данный момент есть только интерфейсы регистрации, активации и входа, а в будущем могут быть реализованы и другие функции, при этом нет теста, по сути можно добавить и тестирование.