koa2从项目搭建到连接mysql再到参数校验

前言:作为一个前端,如果想要学习一些后端的技术,但是又不想话太多成本,koa框架是一个不错的选择。本文将从零开始使用koa框架搭建一个完整后端服务,本文对网上的文章多有借鉴,对参考文章会贴在末尾,但是可能会有缺失,缺失的作者可在评论补充或者私聊我。文章还不完整,后面还会添加登录效验,redis缓存之类的内容。文章仅供参考,有自己的想法可以自己多实现或在评论区与大家交流。
koa官方文档
1 . koa-generator脚手架搭建项目
1.1 安装脚手架

npm install -g koa-generator

1.2 创建项目

koa2 -e project(项目名称) (-e代表使用ejs模板)

1.3 nodemon热更新 packge.json参考

  "scripts": {
    "start": "nodemon bin/www",
    "dev": "./node_modules/.bin/nodemon bin/www",
    "prd": "pm2 start bin/www",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

2 . 连接mysql
2.1 安装mysql

npm install --save mysql

2.2 数据库设置
2.2.1 在根目录下创建config/default.js文件,配置数据库的相关内容

const database = {
  host: 'localhost', // 数据库地址
  port: '3306', // 数据库端口号
  user: 'root', // 数据库登录用户名
  password: 'wdnmddyy', // 数据库登录密码
  database: 'database_01' // 数据库名称
}

module.exports = { database }

2.2.2 根目录下创建db/mysql.js文件,对数据库连接封装

const mysql = require('mysql')
const { database } = require('../config/default')

const pool = mysql.createPool({
  host: database.host,
  port: database.port,
  user: database.user,
  password: database.password,
  database: database.database,
  connectionLimit: 10
})

const query = function (sql, values) {
  return new Promise((resolve, reject) => {
    pool.getConnection(function (err, connection) {
      if (err) {
        // reject(err)
        // console.error(err, '数据库连接失败')
        resolve({
          code: 500,
          msg: `数据库连接失败:${err}`
        })
      } else {
        connection.query(sql, values, (err, results) => {
          if (err) {
            // reject(err)
            resolve({
              code: 400,
              msg: '语句错误:' + err
            })
          } else {
            resolve({
              code: 200,
              data: results
            })
            connection.release() // 连接池释放
          }
        })
      }
    })
  })
}

module.exports = {
  query,
  escape: mysql.escape // escape用于防止xss注入,后面会单独说明
}

2.3 使用

// 获取列表
router.post('/list', async (ctx, next) => {
  const sql = 'select * from database_01.users'
  const res = await query(sql)
  ctx.body = res
})

// 注册
router.post('/register', async (ctx, next) => {
	// 参数校验,后面说明
  const { data, error } = await validator(ctx, registerRules)
  // console.log(data, error)
  if (error) return
  const { name, password } = data
  // ''是字符串,如果是int或者boolean类型则不需要
  const sql = `insert into database_01.users (name, password) values ('${name}', '${password}')`
  const res = await query(sql)
  // 反馈给客户端
  ctx.body = {
    code: res.code,
    msg: res.msg || '注册成功'
  }
})

3 . 处理sql注入与xss攻击
如果先不关心这一块的可以先跳过,如果感兴趣请先阅读以下文章:
第五章:nodejs koa2 mysql redis 全栈开发–安全(sql注入,xss攻击)
3.1 处理sql注入的说明,对于koa2框架使用中间件是框架推荐的设计模式
对于上诉文章的xss案例,经测试使用’'将字符串括起来也能防止xss攻击。
3.2 处理xss攻击,需要依赖xss库,并且通过封装一个中间件来统一处理入参
在这里插入图片描述
3.2.1 根目录下创建middlewares/xss.js

const xss = require('xss') // 需要 npm install xss -S
const XssException = require('../exceptions/xssException')

const xssHandler = async (ctx, next) => {
  try {
    const body = ctx.request.body
    for (const key in body) {
      if (typeof body[key] === 'string') {
        body[key] = xss(body[key])
      }
    }
    // 一定要添加await
    await next()
  } catch (error) {
    // console.error(error)
    throw (new XssException())
  }
}

module.exports = xssHandler

3.2.2 在app.js引入中间件并且使用

const xssHandler = require('./middlewares/xss')

app.use(xssHandler)

4 .错误处理
在这里插入图片描述
4.1 middlewares/exceptions.js中间件处理Error

/**
 * catch error and handle error
 */
const ParamException = require('../exceptions/paramException')
const XssException = require('../exceptions/xssException')

const catchError = async (ctx, next) => {
  try {
    // 一定要添加await
    await next()
  } catch (error) {
  // 错误返回客户端
  // 自定义异常
    if (error instanceof ParamException) {
      ctx.body = error
      return
    }
    if (error instanceof XssException) {
      ctx.body = error
      return
    }
    // 默认处理
    ctx.body = {
      code: 400,
      errorCode: 10000,
      msg: '服务内部错误'
    }
  }
}

module.exports = catchError

4.2 app.js文件注入并且注释掉脚手架自带的错误处理

// const onerror = require('koa-onerror') 脚手架自带
const catchError = require('./middlewares/exception')
app.use(catchError)
// error-handling 脚手架自带
// app.on('error', (err, ctx) => {
//   console.error('server error', err, ctx)
// })

4.3 自定义异常
我们可以通过自定义异常来对Error进行扩展。如上图,在根目录创建exceptions文件夹对所有自定义异常进行管理,并且如4.1代码中可以在错误处理中间件对该异常进行特殊的处理。
4.3.1 自定义异常封装。为了符合面向对象的思想,我们封装一个类对Error进行继承

class XssException extends Error {
  constructor(msg = 'xss解析参数错误', code = 400, errorCode = 10000) {
    super()
    this.msg = msg
    this.code = code
    this.errorCode = errorCode
  }
}

module.exports = XssException

4.3.2 使用

router.post('/list', async (ctx, next) => {
  throw (new ParamException('wdnmd'))
})

5 . 参数校验
对于参数校验,可以自己封装一个中间件来进行处理,文章这里推荐使用async-validator进行处理。因为前端的element-ui和antd都是通过该库来进行数据校验。
async-validator github地址
5.1 封装validator.js:在根目录下创建utils/validator.js

// import Schema from 'async-validator'
const Schema = require('async-validator/dist-node').default

/**
 * 请求参数校验
 * 参考 https://cloud.tencent.com/developer/article/1988905
 * @param ctx
 * @param rules
 * @returns
 */
const validate = async (ctx, rules) => {
  const validator = new Schema(rules)
  let data = null
  switch (ctx.method) {
    case 'GET':
      data = ctx.query
      break
    case 'POST':
      data = ctx.request.body
      break
    case 'PUT':
      data = ctx.request.body
      break
    case 'DELETE':
      data = ctx.query
      break
    default:
      data = ctx.request.body
  }

  return await validator
    .validate(data)
    .then(() => {
      return {
        data,
        error: false
      }
    })
    .catch((err) => {
      // 统一在这里将异常返回给客户端,在业务代码里面就不需要再处理,直接return就行
      ctx.body = {
        code: 400,
        msg: err.errors.map(r => r.message).join(';')
      }
      return {
        data: {},
        error: true
      }
    })
}

module.exports = validate

5.2 将项目的routes结构进行改造,使用controller对所有的校验规则进行管理
在这里插入图片描述

5.3 register参数校验示例

module.exports = {
  // 写法与element-ui的表单规则相同
  score: [
    {
      type: 'number',
      required: true
    },
    {
      validator: (rule, value, callback) => {
        if (value === '23232') {
          callback(new Error('重复'))
        }
        callback()
      }
    }
  ],
  count: {
    type: 'number',
    min: 8,
    required: false,
    message: 'count type error'
  }
}

5.4 接口示例

router.post('/register', async (ctx, next) => {
  const { data, error } = await validator(ctx, registerRules)
  // console.log(data, error)
  // 如果validator返回error为true则不需要继续处理,这里validator已经将错误返回给客户端了。
  if (error) return
  const { name, password } = data
  const sql = `insert into database_01.users (name, password) values ('${name}', '${password}')`
  const res = await query(sql)
  ctx.body = {
    code: res.code,
    msg: res.msg || '注册成功'
  }
})

6 . 参考文章:
6.1 Koa2之koa-generator
6.2 从零一起学koa2(8)—连接MySQL和简单操作
6.3 第五章:nodejs koa2 mysql redis 全栈开发–安全(sql注入,xss攻击)
6.4 koa2异常处理_如何优雅的在 koa 中处理错误
6.5 手把手搭建koa2后端服务器-请求参数与数据校验
7. 源码

  • 13
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是手把手带你koa2 mysql项目的教程。 1. 安装Node.js和npm 首先需要安装Node.js和npm,可以在官网下载安装包进行安装。 2. 初始化项目 在命令行中进入项目目录,运行以下命令初始化项目: ``` npm init ``` 根据提示填写项目信息,完成后会生成package.json文件。 3. 安装koa2和koa-router 运行以下命令安装koa2和koa-router: ``` npm install koa koa-router --save ``` 4. 安装mysql模块 运行以下命令安装mysql模块: ``` npm install mysql --save ``` 5. 创数据库 在mysql中创一个名为test的数据库,并创一个名为users的表,包含id、name、age三个字段。 6. 创连接池 在项目中创一个db.js文件,用于创mysql连接池: ```javascript const mysql = require('mysql'); const pool = mysql.createPool({ host: 'localhost', user: 'root', password: '123456', database: 'test' }); module.exports = pool; ``` 7. 创路由 在项目中创一个router.js文件,用于创koa-router路由: ```javascript const Router = require('koa-router'); const pool = require('./db'); const router = new Router(); router.get('/users', async (ctx) => { const conn = await pool.getConnection(); const [rows] = await conn.query('SELECT * FROM users'); conn.release(); ctx.body = rows; }); module.exports = router; ``` 8. 创服务器 在项目中创一个app.js文件,用于创koa2服务器并引入路由: ```javascript const Koa = require('koa'); const router = require('./router'); const app = new Koa(); app.use(router.routes()); app.listen(3000, () => { console.log('Server is running at http://localhost:3000'); }); ``` 9. 运行项目 在命令行中进入项目目录,运行以下命令启动服务器: ``` node app.js ``` 在浏览器中访问http://localhost:3000/users,可以看到数据库中的用户数据。 至此,一个简单的koa2 mysql项目完成了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值