Egg: use joi for parameter verification and registration interface small demo

Table of contents

Foreword:

Preparation:

Front-end code:

Screenshot of the backend directory:

1. Get parameters

2. Check parameters

3. Query whether the user already exists in the database

4. User storage

5. Test it out

Add user successfully

 Register again with the same username

​Editor's summary:


Foreword:

        Before reading this article, you must already have a preliminary understanding of Egg. As for how to create an egg project, configure the mysql database, etc., I won’t go into details here. If you don’t know, you can go to the official egg to find out- -Egg official document ;

        This article focuses on how to use Joi to verify parameters in Egg, and a small user registration interface development! I don't often write node, so the code is not very standard, please bear with me!

Preparation:

        Let me talk about the user registration process I designed, very simple, a username username, a password password. The uniapp used runs to h5, which looks like this.

        Because the focus is on the backend, no verification will be done in the frontend field, just click the registration button to request the interface we wrote. The backend process is roughly divided into the following steps!

  1. Get the front-end request parameters and perform parameter verification to make the parameters comply with our verification rules!
  2. After the verification is passed, the user name username is used for data query, and duplicate user names are not allowed!
  3. After there is no problem with the user name, encrypt the password!
  4. Store it in the database and return the response content to the front end!

Front-end code:

<template>
	<view class="register">
		<view class="input">
			username:
			<input type="text" v-model="user.username">
		</view>
		<view class="input">
			password:
			<input type="text" v-model="user.password">
		</view>
		<view class="">
			<button @click="formSubmit">注册</button>
		</view>
	</view>
</template>

<script setup>
	import { reactive } from 'vue';

	const user = reactive({
		username: '',
		password: ''
	})

	const formSubmit = () => {
		uni.request({
			url: "http://127.0.0.1:7001/api/user/register",
			method: "POST",
			data: user,
			success: (res) => {
				console.log(res);
			},
			fail: (err) => {
				console.log(err);
			}
		})
	};
</script>

<style lang="scss" scoped>
	.register {
		padding: 100rpx 0;
		width: 700rpx;
		margin: 0 auto;
	}

	.input {
		margin-bottom: 30rpx;

		input {
			border: solid 1px #cecece;
			height: 60rpx;
			padding: 0 20rpx;
		}
	}
</style>

Screenshot of the backend directory:

Focus on the directory files I circled

 

 app/extend/context.js:

This is equivalent to a small package for the returned content, which can be accessed using this.ctx.

module.exports = {
  sendSuccess({ code = 200, data = {}, msg = "ok" }) {
    this.body = { code, data, msg };
  },

  sendFail({ code = 400, data = {}, msg = "fail" }) {
    this.body = { code, data, msg };
  },
};

1. Get parameters

We first need to create a new user.js under app/controller and write the following content!

"use strict";

const { Controller } = require("egg");

class userController extends Controller {
  /* 用户注册 */
  async register() {
    const { ctx, service } = this;
    const { body } = ctx.request;
    console.log(body);
    ctx.sendSuccess({ msg: "egg进行中" });
  }
}

module.exports = userController;

Then create a new user.js in app/router

module.exports = (app) => {
  const { router, controller } = app;
  router.post("/api/user/register", controller.user.register);
};

Finally, write the following content in app/router.js

"use strict";

module.exports = (app) => {
  require("./router/user")(app);
};

 As you can see, we can already get the parameters passed by the front end

2. Check parameters

We  create  a new user.js under app/rules  !

First you need to install Joi, just run npm install joi  ! joi-documentation

const Joi = require("joi");

/* 验证注册信息 */
async function registerValidate(params) {
  const registerSchema = Joi.object({
    username: Joi.string().min(1).max(10).required().messages({
      "string.empty": "用户名不能为空",
      "any.required": "用户名必填",
      "string.max": "用户名长度不能超过10",
    }),
    password: Joi.string()
      .min(6)
      .max(12)
      .pattern(new RegExp("^[a-zA-Z0-9]{6,12}$"))
      .required()
      .messages({
        "string.empty": "密码不能为空",
        "any.required": "密码必填",
        "string.min": "密码长度不低于6",
        "string.max": "密码长度不能超过12",
        "string.pattern.base": "密码只能包含大小写字母以及数字",
      }),
  });
  try {
    await registerSchema.validateAsync(params);
  } catch (error) {
    return error.message ?? "参数错误";
  }
}

module.exports = { registerValidate };

If you ask me why I don't use the officially recommended  egg-validate , the reason is that I am not familiar with it, and custom error messages are uncomfortable. I prefer joi!

In this way, we can  introduce and use it in app/controller/user.js 

"use strict";

const { Controller } = require("egg");
const validate = require("../rules/user");

class userController extends Controller {
  /* 用户注册 */
  async register() {
    const { ctx, service } = this;
    const { body } = ctx.request;
    /* 用户字段验证 */
    const validateResult = await validate.registerValidate(body);
    if (validateResult) {
      ctx.sendFail({ msg: validateResult });
      return;
    }
    ctx.sendSuccess({ msg: "egg进行中" });
  }
}

module.exports = userController;

have a test:

when i don't enter username

Username length is greater than 10

Do not fill in the password

The password filling does not conform to the regular expression

 

Wait, there are some other rules, try it yourself!

3. Query whether the user already exists in the database

Go to our app/service/user.js

const { Service } = require("egg");

class userService extends Service {
  /* 添加用户 */
  async registerUser(params) {
    const { ctx } = this;
    const data = await this.app.mysql.get("users", {
      username: params.username,
    });
    if (data) {
      ctx.sendFail({ msg: "用户名重复,换一个吧" });
      return;
    }
  }
}

module.exports = userService;

4. User storage

Still in  app /service/user.js

We need to execute the npm install bcryptjs command to encrypt the password using the bcryptjs method

const { Service } = require("egg");
const bcrypt = require("bcryptjs");

class userService extends Service {
  /* 添加用户 */
  async registerUser(params) {
    const { ctx } = this;
    const data = await this.app.mysql.get("users", {
      username: params.username,
    });
    if (data) {
      ctx.sendFail({ msg: "用户名重复,换一个吧" });
      return;
    }
    /* 密码入库前加密 */
    params.password = bcrypt.hashSync(params.password, 10);
    const result = await this.app.mysql.insert("users", params);
    return result.affectedRows === 1;
  }
}

module.exports = userService;

 We need to connect to the database operation in app/controller/user.js

"use strict";

const { Controller } = require("egg");
const validate = require("../rules/user");

class userController extends Controller {
  /* 用户注册 */
  async register() {
    const { ctx, service } = this;
    const { body } = ctx.request;
    /* 用户字段验证 */
    const validateResult = await validate.registerValidate(body);
    if (validateResult) {
      ctx.sendFail({ msg: validateResult });
      return;
    }
    /* 进行数据库操作 */
    try {
      const result = await service.user.registerUser(body);
      if (result) {
        ctx.sendSuccess({ msg: "用户添加成功!" });
      }
    } catch (error) {
      ctx.sendFail({ msg: "用户添加失败!" });
    }
  }
}

module.exports = userController;

5. Test it out

Add user successfully

 Register again with the same username

Summarize:

It feels good to use egg to write back-end services. It works out of the box and has formulated a series of rules. You can write code according to the rules, and it has high scalability, which is really not bad!

 

Guess you like

Origin blog.csdn.net/qq_42543244/article/details/129425292