当前位置: 首页 > news >正文

【Node.js+koa--后端管理系统】用户注册接口设计 | 连接Mysql数据库 | 校验注册权限

多一些不为什么的坚持 \color{#0000FF}{多一些不为什么的坚持} 多一些不为什么的坚持 🙊

贤蛋🥚大眼萌,一名很普通但不想普通的程序媛 \color{#FF0000}{贤蛋 🥚大眼萌 ,一名很普通但不想普通的程序媛} 贤蛋🥚大眼萌,一名很普通但不想普通的程序媛🤳

📝本文章收录于专栏:Node.js+koa–后端管理系统

🍳该项目收录于github:ITClub

用户注册接口设计 | 连接Mysql数据库 | 校验注册权限

    • 🚀 用户注册接口设计
      • ① 编写流程
      • ② 注册用户路由
      • ③ 控制层处理函数
      • ④ 数据库操作
    • 🏓 连接Mysql数据库
      • ① 安装 mysql2
      • ② 连接数据库
    • 🥁 注册用户校验
      • ① 创建数据库用户表
      • ② 创建错误信息处理文件
      • ③ 编写验证用户是否存在中间件
      • ④ MD5加密密码

🚀 用户注册接口设计

① 编写流程

  • 注册用户路由router编写;
  • 处理函数的控制器controller编写;
  • 操作数据库的service编写;

采用分层架构的思维,不同的模块处理不同的内容。

image-20220916110624685

注意:需要安装koa对body解析的依赖

image-20220522115112062

//目录:@/oruter/index.js
// 封装路由
const fs = require ('fs')

const useRoutes = function (){
 fs.readdirSync(__dirname).forEach(file=>{
   if(file === 'index.js') return;
   const router = require(`./${file}`)
   this.use(router.routes());
   this.use(router.allowedMethods())
 })
}
module.exports = useRoutes
//目录:@/app/index.js
const Koa = require("koa")
const bodyParser = require("koa-bodyparser")

const useRoutes = require('../router') // 创建路由
const errorHandler = require('./error_handle') // 错误处理文件

const app = new Koa()

app.useRoutes = useRoutes;

app.use(bodyParser())
app.useRoutes()
app.on('error',errorHandler) //触发错误处理函数

module.exports = app

② 注册用户路由

// 目录: @/router/user_router.js
const Router = require("koa-router")

const { create } = require("../controller/user_controller")

const userRouter = new Router({ prefix: "/users" })

userRouter.post("/", create)

module.exports = userRouter

③ 控制层处理函数

// 目录: @/controller/user_controller.js
const userService = require("../service/user_service")

class UserController {
  // 创建用户
  async create(ctx, next) {
    const user = ctx.request.body
    const results = await userService.create(user)
    ctx.body = results
  }
}

module.exports = new UserController()

④ 数据库操作

先编写数据库操作语句,后面单独将数据库连接处理

image-20220916112513858

// 目录: @/service/user_service.js
const connection = require("../app/database")

class UserService {
  async create(user) {
    // 将user储存到用户表中
    const statement = `INSERT INTO user (name,password) VALUES(?,?);`
    // console.log("用户存入数据库成功");
    return results[0]
  }
}
module.exports = new UserService()

🏓 连接Mysql数据库

① 安装 mysql2

npm install mysql2

image-20220523103351757

② 连接数据库

这里的环境变量需要自己在.env环境配置文件中填写,这样只需要在.env文件中修改数据库配置信息就可以了。

image-20220916113735392

image-20220523110209694

// 目录: @/app/database.js
// 完整的数据库连接配置
const mysql = require('mysql2')

const config = require('./config')

const connections = mysql.createPool({
  host: config.MYSQL_HOST,
  port: config.MYSQL_PORT,
  database: config.MYSQL_DATABASE,
  user: config.MYSQL_USER,
  password: config.MYSQL_PASSWORD
});

connections.getConnection((err,conn)=>{
  conn.connect((err)=>{
    if(err){
      console.log('连接数据库失败',err);
    }else(
      console.log('连接数据库成功')
    )
  })
})

module.exports = connections.promise();

🥁 注册用户校验

编写用户注册的中间件,用户写入用户名和密码,编写中间件verifyUser判断用户是否已经存在在数据库中。

image-20220916140722236

① 创建数据库用户表

# 创建用户表
CREATE TABLE IF NOT EXISTS `user`(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(30) NOT NULL UNIQUE,
	password VARCHAR(50) NOT NULL,
	createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

② 创建错误信息处理文件

独立编写一个错误常量文件(完整)(@/app/error_handle.js)

// 目录: @/constants/error_types.js
const NAME_OR_PASSWORD_IS_REQUIRED = 'name_or_password_is_required';
const USER_ALREADY_EXISTS = 'user_already_exists';
const USER_DOES_NOT_EXISTS = 'user_does_not_exists';
const PASSWORD_IS_INCORRENT = 'password_is_incorrent';
const UNAUTHORIZATION = 'UNAUTHORIZATION';
const UNPERMISSION = 'unpermission';

module.exports = {
  NAME_OR_PASSWORD_IS_REQUIRED,
  USER_ALREADY_EXISTS,
  USER_DOES_NOT_EXISTS,
  PASSWORD_IS_INCORRENT,
  UNAUTHORIZATION,
  UNPERMISSION
}
const errorTypes = require('../constants/error_types')

const errorHandler = (error,ctx) =>{
//  // 这里的 error.message = new Error(里面的值)
  let status,message;
  switch(error.message){
    case errorTypes.NAME_OR_PASSWORD_IS_REQUIRED:
      // console.log(error.message);
      status = 400; //Bad Request
      message = "用户名和密码不能为空"
      break;
    case errorTypes.USER_ALREADY_EXISTS:
      status = 405; //conflict
      message = "用户名已存在"
      break;
    case errorTypes.USER_DOES_NOT_EXISTS:
      status = 400; //conflict
      message = "用户名不存在"
      break;  
    case errorTypes.PASSWORD_IS_INCORRENT:
      status = 400; //conflict
      message = "密码错误"
      break;  
    case errorTypes.UNAUTHORIZATION:
      status = 401; //unauthorization
      message = "token无效"
      break;  
    case errorTypes.UNPERMISSION:
      status = 401; //unauthorization
      message = "您不具备权限"
      break; 
    default:
      status = 404;
      message = "默认错误";
}
  ctx.status = status;
  ctx.body = message;
}

module.exports = errorHandler;

image-20220523165022089

③ 编写验证用户是否存在中间件

// 目录: @/middleware/user_middleware.js
const errorTypes = require("../constants/error_types")
const serviece = require("../service/user_service")

const verifyUser = async (ctx, next) => {
  console.log("用户注册验证middleware")
  // 1.获取用户名和密码
  const { name, password } = ctx.request.body
  // console.log(name,password);

  // 2.判断用户名或者密码不能为空
  if (!name || !password || name === "" || password === "") {
    const error = new Error(errorTypes.NAME_OR_PASSWORD_IS_REQUIRED)
    //   // 发射错误信息
    //   console.log(error);
    return ctx.app.emit("error", error, ctx)
  }
  // 3.判断这次注册的用户名是注册过的
  const results = await serviece.getUserByName(name)
  if (results.length) {
    const error = new Error(errorTypes.USER_ALREADY_EXISTS)
    return ctx.app.emit("error", error, ctx)
  }
  await next()
}
module.exports = {
  verifyUser
}
 // 目录: @/service/user_service.js
// 查询用户是否存在数据库中
  async getUserByName(name) {
    const statement = `SELECT *FROM user WHERE name = ?;`
    const results = await connection.execute(statement, [name])
    return results[0]
  }
image-20220523164508748

④ MD5加密密码

将用户注册的密码拦截之后加密,再存储到数据库中,防止数据库泄露,这里采用MD5加密

npm install blueimp-md5

创建 handlePassword 函数,在user_middleware.js中中间件verifyUser中插入

const handlePassword = async (ctx, next) => {
  const { password } = ctx.request.body
  ctx.request.body.password = md5password(password)
  await next()
}

创建工具函数,处理MD5密码加密(@/utils/password_handle.js)

image-20220524110239114

在这里插入图片描述

相关文章:

  • 30岁年薪28W,我还是没顶住压力跳槽了····
  • boost之string_ref
  • Java实现拼图小游戏(1)—— JFrame的认识及界面搭建
  • Java成品网站推荐 毕设从这起步就够了
  • P4 开发实践 — NG-SDN Tutorial — Exercise 5: IPv6 Routing
  • Android Studio Dolphin | 2021.3.1 发布,快来看看有什么更新吧~
  • 常见软件---SQLite3的C语言下使用
  • 嵌入式C语言(入门必看)
  • 神经网络解决优化问题,神经网络 样本不平衡
  • java 使用curl 超时无返回结果问题 有请求 无响应 卡死问题
  • BERT知识蒸馏Distilled BiLSTM
  • 启明智显分享|基于ESP32-S3方案的4寸86盒开发板快速开发及烧录
  • 浅谈地下污水处理厂电气特点和能效管理系统的实际应用
  • 【JavaScript】巩固JS开发中五个常用功能/案例(46-50)(牛客题解)
  • 2.5 贝叶斯分类器
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 2017-08-04 前端日报
  • es6--symbol
  • Java深入 - 深入理解Java集合
  • Koa2 之文件上传下载
  • Laravel5.4 Queues队列学习
  • MySQL主从复制读写分离及奇怪的问题
  • Nacos系列:Nacos的Java SDK使用
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • socket.io+express实现聊天室的思考(三)
  • 聊聊flink的BlobWriter
  • 马上搞懂 GeoJSON
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用common-codec进行md5加密
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 译自由幺半群
  • 1.Ext JS 建立web开发工程
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • #100天计划# 2013年9月29日
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (6)设计一个TimeMap
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (汇总)os模块以及shutil模块对文件的操作
  • (六)c52学习之旅-独立按键
  • (排序详解之 堆排序)
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (正则)提取页面里的img标签
  • (转)Google的Objective-C编码规范
  • (转)Oracle存储过程编写经验和优化措施
  • (转)winform之ListView
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)