node连接mysql以及防注入的手段

386 阅读1分钟

前言✨

后端技术栈: koa2 + mysql

sql注入: SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

koa2连接mysql

1.安装mysql.js

$ yarn add mysql

2.建立连接池、常用sql语句

// mysql.js
const mysql = require('mysql');
// 创建连接池
const pool = mysql.createPool({
    host: 'xxx.xx.xxx.xxx', // 服务器ip
    port: 3306, // mySql运行的端口号(默认3306)
    database: 'name', // 数据库名称
    user: 'user', // 数据库用户
    password: xxxx // 数据库密码
})
const query = (sql, values) => {
    return new Promise((resolve, reject) => {
        pool.getConnection(function (err, connection) {
            if (err) {
                reject(err)
            } else {
                connection.query(sql, values, (err, rows) => {
                    if (err) {
                        reject(err)
                    } else {
                        resolve(rows)
                    }
                    connection.release()
                })
            }
        })
    })
}

/**
 * 查询数据
 * @param {*} table 表名
 * @param {*} key 查询条件的Key
 * @returns list
 */
const findDataWhere = (table, word, key = 'id') => {
    const _sql = `SELECT * FROM ??  WHERE ${key} =?`
    return query(_sql, [table, word])
}

/**
 * 插入数据
 * @param {*} table 表名
 * @param {*} values 插入的值
 * @returns list
 */
const insertData = (table, values) => {
    const _sql = `INSERT INTO ?? SET ?`
    return query(_sql, [table, values])
}

/**
 * 更新数据
 * @param {*} table 表名
 * @param {*} values 插入的值
 * @param {*} word 查询条件的值 
 * @param {*} key 查询条件的Key
 * @returns list
 */
const updateData = (table, values, word, key = 'id') => {
    const _sql = `UPDATE ?? SET ? WHERE ${key} =? `
    return query(_sql, [table, values, word])
}

/**
 * 删除数据
 * @param {*} table 表名
 * @param {*} word 查询条件的值
 * @param {*} key 查询条件的Key
 * @returns 
 */
const deleteData = (table, word, key = "id") => {
    const _sql = `DELETE FROM ?? WHERE ${key} =?`
    return query(_sql, [table, word])
}
module.exports = {
    query,
    insertData,
    updateData,
    deleteData,
    findDataWhere
}

可以看到我封装的增删查改sql,有几个晦涩的点,比如'INSERT INTO ?? SET ?' 这个???就是connection.query()使用 ?做为查询参数占位符,??做表名占位符。在使用查询参数占位符时,在其内部自动调用connection.escape()方法对传入参数进行编码,来防止sql注入。

3.使用方法

// 控制层 article.js
const mySqlFun = require("./mysql")
/**
 * 获取标签列表(id倒序)带分页
 */
const findLabelListPage = async (ctx) => {
    let { pageIndex = 1, pageSize = 10, } = ctx.query
    let resData = {
        list: [],
        pageIndex: pageIndex,
        pageSize: pageSize,
    }
    const _sql = `SELECT * FROM ?? ORDER BY id DESC LIMIT ${(pageIndex - 1) * pageSize},${pageSize} `
    // 使用上面导出的query,第一个参数就是sql,第二个参数是数组,?? 和 ? 就是占位符对应的具体表名或参数
    let res = await mySqlFun.query(_sql, ['label'])
    if (res) {
       ...
    } else {
       ...
    }
}