Node.js+Express+mongoDB 实现邮箱注册

850 阅读4分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

很多网站都会有用户注册这一个功能模块,其中大多数网站都会让用户填写手机号,然后通过手机验证码来实现用户的注册。但是大家都知道手机验证码都会收取一定的费用,所以有一些网站可能资金不够,但是又想尽大可能的留住用户,所以他们就采用使用邮箱验证码的方式来进行注册。

1.采用的技术栈

前端:vue2.x

后端:Express+mongoose

数据存储:mongodb

2.整体实现思路

(1)前端收集用户信息,包括邮箱。

(2)用户点击获取邮箱验证码,调取后端获取验证码的接口。

(3)后端生成随机验证码,发送到用户邮箱,且将此验证码保存到数据库中,并设置一定的失效时间。

(4)用户填写验证码,调用注册接口。

(5)后端接收验证码,与数据库中相对比,成功则注册,否则验证码错误。

3.具体实现代码

(1)在express项目中安装邮件发送模块中间件

npm install nodemailer
npm install nodemailer-smtp-transport

(2)定义获取验证码接口

我的项目对路由进行了封装,在routes文件夹下面新建了route.js文件,作为路由入口,定义获取验证码接口如下:

//routes/route.js

const user = require("./user"); // 用户相关路由模块
router.post("/user/emailCode", user.emailCode); // 获取邮件验证码

(3)编写获取验证码接口方法

//routes/user.js

const User = require("../database/models/user"); // 用户数据库模型
const Code = require("../database/models/code"); // 验证码数据库模型
const nodemailer = require("nodemailer"); // 邮件发送模块
const smtpTransport = require("nodemailer-smtp-transport");

const user = {
  // 获取邮箱验证码
  emailCode: async (req, res) => {
    /*邮件发送的基本配置*/
    const transport = nodemailer.createTransport(
      smtpTransport({
        host: "smtp.163.com", // 服务,这里使用的是163邮箱
        port: 465, // smtp端口,默认就是此 端口
        secure: true,
        auth: {
          user: "xxx@163.com", //发件人邮箱,即你的邮箱
          pass: "xxxxxxxx", // SMTP授权码,需要邮箱设置中获取
        },
      })
    );
    /* 生成验证码 */
    const randomFns = () => {
      // 生成6位随机数
      let code = "";
      for (let i = 0; i < 6; i++) {
        code += parseInt(Math.random() * 10);
      }
      return code;
    };
    const regEmail =
      /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/; //验证邮箱正则

    /* 发送验证码 */
    let EMAIL = req.body.email;
    if (regEmail.test(EMAIL)) {
      let code = randomFns();
      transport.sendMail(
        {
          from: "lhqhacker@163.com", // 发件邮箱
          to: EMAIL, // 收件列表
          subject: "验证你的电子邮件", // 标题
          html: `
            <p>你好!</p>
            <p>您正在注册小猪社区账号</p>
            <p>你的验证码是:<strong style="color: #ff4e2a;">${code}</strong></p>
            <p>***该验证码10分钟内有效***</p>`, // html 内容
        },
        function (error, data) {
          if (error) {
            transport.close(); // 如果没用,关闭连接池
          }
        }
      );

      /* 存储验证码到数据库中 */
      const e_mail = EMAIL;
      await Code.deleteMany({ e_mail });
      const [data] = await Code.insertMany({ e_mail, code: code });
      setTimeout(async () => {
        //10分钟后失效,即删除验证码
        await Code.deleteMany({ e_mail });
      }, 1000 * 60 * 10);
      res.json(res.setUnifyResFormat(null, "00000", "邮件发送成功"));
    } else {
      res.json(res.setUnifyResFormat(null, "E0001", "邮件格式错误"));
    }
  },
};
module.exports = user;

上面代码中只有一个emailCode方法,目的就是使用我们自己的邮箱发送验证码到用户的邮箱中去,其中涉及到有mongoose的知识需要小伙伴们自己去学习了,也可以在评论区留言。

(4)前端调用注册接口

//routes/user.js

const User = require("../database/models/user"); // 模型
const Code = require("../database/models/code");
const tokenSetAndVer = require("../utils/token"); // 设置token和校验token
const bcryptjs = require("bcryptjs"); // 密码加密

// 邮件发送模块
const nodemailer = require("nodemailer");
const smtpTransport = require("nodemailer-smtp-transport");

const user = {
  // 注册
  register: async (req, res) => {
    /* 前端传来的基本信息 */
    const username = req.body.username;
    const e_mail = req.body.email;
    const code = req.body.code;
    const password = req.body.password;
    const vire = await Code.findOne({ e_mail, code }); // 检验验证码
    if (!vire) {
      res.json(res.setUnifyResFormat(null, "U0001", "验证码填写错误!"));
      return;
    }

    /* 如果验证码校验通过,则校验用户信息 */
    User.findOne(
      {
        email: e_mail,
      },
      (err, doc) => {
        if (doc) {
          res.json(res.setUnifyResFormat("", "U0001", "邮件已被注册了!"));
          return;
        }
        // 保存用户注册的信息到数据中
        let user = new User({
          username: username,
          password: password,
          email: e_mail,
        });
        // 保存用户
        user.save(async (err, doc) => {
          if (err) {
            res.json(res.setUnifyResFormat(null, "D0001", err));
          } else {
            Code.deleteMany({ e_mail }); // 删除验证码
            // 生成token
            const token = await tokenSetAndVer.setToken(user.uid, user.role);
            res.setHeader("Authorization", "Bearer " + token);
            res.json(res.setUnifyResFormat(doc, "00000", "注册成功"));
          }
          return;
        });
      }
    );
  },
};
module.exports = user;

上面代码同样编写在user.js文件中,这个方法主要的作用就是校验验证码、生成token、存储用户到数据库中,对于token方面的之后我后续在补充。

总结

到这里邮箱验证码注册的功能基本算是实现了,这里主要借助了两个中间件。整个流程不算太复杂,还不赶紧运用到你的网站中去,有问题欢迎评论区留言。