使用 NodeJS 在 mySQL 中插入多条记录以防止注入并获取每条记录的 ID

Posted

技术标签:

【中文标题】使用 NodeJS 在 mySQL 中插入多条记录以防止注入并获取每条记录的 ID【英文标题】:Inserting multiple records in mySQL with NodeJS preventing injection and getting each record's ID 【发布时间】:2019-10-15 00:06:05 【问题描述】:

我有一个将一条或多条记录添加到表中的 ajax 请求(以下代码是服务器端的):

app.post('/saveLesson',function(req, res) 

    let sections = JSON.parse(req.body.sections);

    let sql = 'INSERT INTO sections (title, content, duration) VALUES ';

    for (let i = 0; i < sections.length; i++) 

        if (i == sections.length-1) 
            sql += '("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '");';
         else 
            sql += '("' + sections[i].title + '","' + sections[i].content + '","' + sections[i].duration + '"),';
        
    
    connection.query(sql, 
        function (error, result) 
            if (error) throw error;
    );

);

我想防止 SQL 注入,但我不确定如何针对多条记录执行此操作。

通常我知道我必须按如下方式构建我的 sql 语句:

connection.query("SELECT * FROM bank_accounts WHERE dob = ? AND bank_account = ?",
    [
     req.body.dob,
     req.body.account_number
    ],
    function(error, results)  

    
);

但我不确定如何使用多条记录来实现这一点(不知道它们有多少)。 .query 参数只是一个常规数组吗?

另外,我需要将创建的 ID 存储在某处并将它们发送回客户端页面。我怎样才能做到这一点?谢谢。

********************************** 更新 ***************** ************

虽然有人发布了解决方案,但我认为这可能有用。使用以下代码,您可以添加多条记录以防止 SQL 注入。

app.post('/saveLesson',function(req, res) 

    let sections = JSON.parse(req.body.sections);

    console.log(sections);

    let sql = 'INSERT INTO sections (title, duration, content) VALUES ';

    // I make a new array to pass the list of values to the query
    let sectionsParamList = [];

    for (let i = 0; i < sections.length; i++) 

        if (i == sections.length-1) 
            sql += '(?,?,?);';
         else 
            sql += '(?,?,?),';
        

        sectionsParamList.push(sections[i].title);
        sectionsParamList.push(sections[i].duration);
        sectionsParamList.push(sections[i].content);
    

    connection.query(sql, sectionsParamList,
        function (error, result) 
            if (error) throw error;
    );

);

【问题讨论】:

Also I need to store somewhere the created IDs and send them back to the client page. 您可以自己生成主键,而不是使用自动增量主键,即microshell.com/database/mysql/… 有趣的链接,谢谢。在客户端,我还有要插入的记录的 ID(增量数字 + Math.random() - 这些仅在客户端页面中是唯一的,而不是在数据库中)。是否建议将具有此 ID 的记录与其他信息一起添加,然后使用“虚拟”ID 检索由数据库创建的唯一 ID?我想我最终会得到一个无用的字段,除非我为其他数据回收它。 【参考方案1】:

MySQL 的工作方式是,当您像您建议的那样执行多行INSERT 操作时,您只能取回插入的最后一行的自动生成的唯一id。它在您的result 对象中显示为result.insertId。不要试图猜测其他行的 id 值,例如通过减法,因为不能保证。

您插入的每一行都需要id,这意味着您不应使用多行插入,而应使用单行插入序列。这也巧妙地解决了您的 SQL 注入问题。

但是您必须弄清楚如何进行一系列INSERT 操作。您可能希望使用 async / await / promise 设置来做到这一点。像这样的东西,未调试

/* do one insert with a Promise so you can await it */
function doInsert (section, connection) 
   const values = [section.title, section.content, section.duration];
   return new Promise( function ( resolve, reject ) 
      const sql = "INSERT INTO sections (title, content, duration) VALUES (?,?,?);"
      connection.query (sql, values, function ( error, result ) 
         if (error) reject (error)
         resolve (result.insertId)
       )
    )


/* do all the inserts, awaiting each one */
async function doInserts (sections, connection) 
  let ids = []
  for (let i = 0; i < sections.length; i++) 
     const id = await doInsert (sections[i], connection) 
     ids.push(id) 
  
  return ids

/* handle your post */
app.post('/saveLesson',function(req, res) 
  let sections = JSON.parse(req.body.sections)
  /* get the result back from an async function with .then / .catch */
  doInserts (sections, connection)
  .then (function (resultIds) 
     /* respond with the id values in a JSON object */
     res.status(200).json(resultIds)
   )
  .catch ( function (error) 
     /* respond with an error */
     res.status(500).json(error)
   )
 )

如果您还不了解这些 async / await 和 Promise 语言结构,那么您真的值得您学习它们。

【讨论】:

我承认我对 async / await 和 Promise 了解不多。我绝对需要学习如何使用它们。谢谢你的帖子。

以上是关于使用 NodeJS 在 mySQL 中插入多条记录以防止注入并获取每条记录的 ID的主要内容,如果未能解决你的问题,请参考以下文章

在一个查询中使用 MySqlCommand 将多条记录插入 MySQL C# (MySQLConnector) & command 转义引号的参数

eggjs mysql 批量插入多条

如果 mysql 数据库中的表中不存在,则更新或插入多条记录

JAVA中,向MYSQL插入多条数据,如何判断如果某记录已经存在就不插入

MySQL插入查询一次插入多条记录

sql server返回插入记录的ID(多条记录)