Nodejs realizes user mailbox registration

                                                    Preface

 

This blog post describes the implementation process of user registration from a practical perspective. The entire project is built using the koa2 framework.

The user registration process is briefly described as follows: the user sends three fields user_name, password password and email to the interface address. After the backend accepts it, inserts a new record into the user table in the database, but sets the status of the user record It is unavailable. Then a verified url is sent to the user's mailbox. After the user opens the address in the mailbox, the status of the user record corresponding to the database is changed from unavailable to available. After this, the user registration function is completed.

The user data table is as follows

                                      

githup complete project address

 

 

                                            Quickly build the project

 

Create a new project folder, enter npm init -y under the command line tool to initialize the project. Use npm to install the corresponding dependency packages, as follows:

npm i @koa/router koa koa-bodyparser sequelize mysql2 --save
npm i nodemon -D
  • koa/router is used to build routes. The koa-bodyparser middleware allows the backend to easily receive the parameters passed by users using POST requests. sequelize and mysql2 are the dependencies required to operate the database
  • nodemon can monitor file changes in real time and automatically update nodejs code to improve development efficiency

  The project directory is as follows:

                                                  

app.js is the entry file of the entire project, which introduces the routing module router and bodyParser middleware respectively, and uses the app instance to load it. As follows:

const Koa = require('koa');
const app = new Koa();
const { router } = require('./router/user'); //引入用户路由模块
const bodyParser = require('koa-bodyparser');

app.use(bodyParser()); //解析post请求
app.use(router.routes()); //加载用户路由模块

//用户如果访问根地址,返回'Hello world'
app.use((ctx) => {
  ctx.body = 'Hello world';
});

app.listen(3000);

user.js defines the user's routing module, as follows:

const Router = require('@koa/router');

const router = new Router();

/**
 * 注册
 *
 * 用户如果访问/register,就返回'注册'
 */
router.get('/register', async (ctx) => {
  ctx.body = '注册';
});

exports.router = router;

Finally, configure the startup parameters in pakage.json

                                    

Go back to the project root directory, open the command line tool and run npm run dev to successfully start the project. At this time, open the browser access interface address to see the data return.

                                                                   

                                                                 

                                         

 

                                              Registration function

 

Change the registered interface to the post method, and you can easily get the three fields sent by the user through ctx.request.body. The mission of the routing layer ends here, and the rest of the work is handled by the business layer. Give ctx.body The data will be returned to the user, which means that the results of the business layer processing are directly returned to the user.

/**
 * 注册
 */
router.post('/register', async (ctx) => {
  const { user_name, password, email } = ctx.request.body; //在app.js中使用bodyParser中间件后,这里可以轻松获取到post请求传递过来的参数
  ctx.body = await register({ user_name, password, email });
});

The register function of the business layer is the core code for realizing registration (as follows). To register a new user, you must first determine whether the user has registered. If the user name user_name and email address have been registered, it will not proceed and return an error message to the user. If it is a new user registration, a new user record whose status is unavailable is added to the database, and then a verified address email is sent to the user mailbox.

  • userIsExist is a function of the persistence layer. By passing it a user_name field, it will generate SQL statements to query in the database to determine whether anyone in the database has registered the user name. The functions implemented by the persistence layer function are all direct operations Database, specifically how to write and view the project source code.
  • If you pass in the email field to userIsExist, then it will take this email to the database to check to see if anyone has registered this mailbox
  • Enter npm i uuid --save in the command line tool, by installing the uuidv4 package, a random string can be generated, and we use it as the check code for email verification
  • addUser is a function for adding users to the persistence layer, and it will add a new user record to the user table
  • The sendRegisterEmail function is responsible for sending emails to users.
/**
 * 注册
 */
exports.register = async ({ user_name, password, email }) => {
  //判断用户是否存在
  const userInfo = await userIsExist({ user_name });
  if (userInfo !== null && userInfo.status !== 1) {//userInfo.status决定该用户状态不可用
    //用户已存在
    return userExist();//自定义错误函数,返回值形似{"error_no": "100","message":"用户已存在"}
  }
  //判断邮箱是否存在
  const emailInfo = await userIsExist({ email });
  if (emailInfo !== null && emailInfo.status !== 1) {
    //邮箱已存在
    return emailExist();
  }
  //生成邮箱校验码
  const verify_key = uuidv4();

  const data = userInfo || emailInfo;

  let result = null;

  if (data) {
    //已经存在用户数据了,但是该用户没有验证,所以重新发送一封邮件让用户验证
    await updateUserInfo({
      user_id: data.user_id,
      verify_key,
    });
    sendRegisterEmail({ user_id: data.user_id, email, verify_key }); //发送校验邮箱
  } else {
    //新增用户
    result = await addUser({
      user_name,
      password: md5(password),
      email,
      verify_key,//随机生成字符串
    });
    const { user_id, email, verify_key } = result;
    sendRegisterEmail({ user_id, email, verify_key }); //发送校验邮箱
  }
  return new Success(result);//新增成功
};

 

 

                                             Mailbox verification

 

At the end of the above user registration, call sendRegisterEmail(( user_id: data.user_id, email, verify_key )) to send an email to the user's mailbox. The verify_key is a randomly generated verification code, which has been stored in the database of the new user.

Next, we have to construct a link as follows, and send it to the user by email to let them click on the final registration process.

http://localhost:8081/regiter_success?id=5&verify_key=e408c17f-ec26-4847-a633-c39cd6621f49

By observing this link, we can see that /register_success is an interface that needs to be developed separately. id corresponds to user_id, and verify_key is a randomly generated string. If the user clicks on the link, we can get user_id and verify_key in this interface. Pass The user_id goes to the database to query the user record. If it is found that the verify_key stored in the user record in the database and the verify_key obtained from the interface are equal, the status of the record can be set as available. So far, the entire registration verification process is counted. The curtain ends.

Next, I will delve into how to write the sendRegisterEmail function. If you want the nodejs server to send emails, you can use the third-party package nodemailer to help us easily achieve it. Run npm i nodemailer --save to install the dependencies. Then create a new file to associate nodemailer The API is encapsulated into a tool method sendRegisterEmail for external calls.

const nodemailer = require('nodemailer');
const { service_ip } = require('../config');

const transporter = nodemailer.createTransport({
  host: 'smtp.qq.com', //QQ邮箱的服务器
  port: 587, //端口号
  secure: false, //465为true,其他为false
  auth: {
    user: '[email protected]', // 自己的邮箱
    pass: '-------', // 授权码,邮箱的授权码
  },
});

/**
 * 注册用户时发送邮箱
 */
exports.sendRegisterEmail = ({ user_id, email, verify_key }) => {
  const url = `${service_ip}/regiter_success?id=${user_id}&verify_key=${verify_key}`;
  const params = {
    from: '奥巴马<[email protected]>', // 收件人显示的发件人信息,xxxxxxx换成自己的qq
    to: email, // 目标邮箱号
    subject: '注册新用户',
    html: `点击链接即可注册完毕:<a style="color:red" href="${url}">${url}</a>`,
  };
  return sendMsg(params);
};

/**
 * 找回密码时发送校验码
 * @param {*} params
 */
exports.sendCode = ({ email, verify_key }) => {
  const params = {
    from: '奥巴马<[email protected]>', // 收件人显示的发件人信息,xxxxxxx换成自己的qq
    to: email, // 目标邮箱号
    subject: '找回密码',
    html: `邮箱验证码:${verify_key}`,
  };
  return sendMsg(params);
};

/**
 * 发送消息
 */
const sendMsg = (params) => {
  return new Promise((resolve) => {
    transporter.sendMail(params, (err, data) => {
      resolve(null);
      transporter.close(); //发送完毕后关闭
    });
  });
};

There are two places in the above tool method that need to be changed, the first [email protected] needs to be changed to its own qq email address, and nodejs uses this mailbox to send emails to users. The second place is required. Fill in the authorization code distributed by changing the mailbox.

So how to get the authorization code? Take qq mailbox as an example. Click on the settings of the mailbox-account-POP3/SMTP service to open, you can get the mailbox authorization code.                            

The user has now received the email and clicked the link address of the mailbox. The address interface /regiter_success needs us to continue to develop. What it does is to verify the correctness of the random string and set the user status as available.

Routing layer:

/**
 * 注册成功
 */
router.get('/regiter_success', async (ctx) => {
  const { id: user_id, verify_key } = ctx.query;
  ctx.body = await verifyKey({ user_id, verify_key });
});

Business Layer:

/**
 * 注册时验证key值对不对
 * @param {*} param0
 */
exports.verifyKey = async ({ user_id, verify_key }) => {
  const userInfo = await userIsExist({ user_id, verify_key });
  if (userInfo === null) {
    return keyUnValid();//无效的校验码
  }
  await updateUserInfo({ //认证成功将verify_key置为"",并是用户状态status置为可用
    verify_key: '',
    user_id,
    status: 0,
  });
  return new Success();
};

 

 

                                            recover password

 

The knowledge points used for password retrieval are similar to registration. The user needs to send two fields to the backend to retrieve the password, namely the mailbox email and the new password password, and the user's database record can be found through the mailbox to reset the password. But In order to ensure that the person who wants to modify the password is the true owner of the mailbox, you must first send a verification code code to the mailbox. In addition to sending the above two fields to the backend, the user also needs to send the verification code received by his mailbox. After receiving these three fields, the backend can verify the authenticity of the user and reset the password.

 

 

Guess you like

Origin blog.csdn.net/brokenkay/article/details/108263190